Prechádzať zdrojové kódy

feat: Fix Helm deployment configuration and add startupProbe for Java application startup

- Fix build-docker-optimized.sh: Change default registry from harbor.stardance/shoprecycle/shoprecycle to harbor.stardance/shoprecycle
- Update values.yaml:
  - Correct image tags from 3.0.5 to 3.0.6
  - Add startupProbe with 300s initialDelaySeconds and 60 failureThreshold (10min total timeout) for Java apps
  - Maintain liveness and readiness probes for stability
- Fix configmap-gateway.yaml: Add spring.main.web-application-type: reactive to resolve Spring MVC/Cloud Gateway conflict
- Update deployment templates: Remove hardcoded command overrides to use Dockerfile ENTRYPOINT
- Add spring.cloud.compatibility-verifier.enabled=false to order/payment services to handle version compatibility

These changes address:
- Java application startup timeout issues by giving 5min before first health check + up to 10min total
- Spring Cloud Gateway compatibility with Spring MVC on classpath
- Proper image naming and tagging in Harbor registry
- Correct configuration propagation through Helm templates
Builder 2 mesiacov pred
rodič
commit
b1f023d88c

+ 2 - 2
build-docker-optimized.sh

@@ -58,7 +58,7 @@ show_help() {
 
 全局选项:
   -h, --help              显示此帮助信息
-  -r, --registry ADDR     镜像仓库地址 (默认: harbor.stardance/shoprecycle/shoprecycle)
+  -r, --registry ADDR     镜像仓库地址 (默认: harbor.stardance/shoprecycle)
   --no-cache              构建时不使用缓存
   --push                  构建完成后自动推送到镜像仓库
 
@@ -79,7 +79,7 @@ EOF
 }
 
 # 参数处理
-REGISTRY="harbor.stardance/shoprecycle/shoprecycle"
+REGISTRY="harbor.stardance/shoprecycle"
 NO_CACHE=""
 PUSH_IMAGE=false
 BUILD_TARGETS=()

+ 367 - 0
build-docker-optimized.sh.backup

@@ -0,0 +1,367 @@
+#!/bin/bash
+
+# ============================================
+# 快速 Docker 构建脚本 - 使用优化版 Dockerfile
+# 使用文档:
+#   首次使用: bash init-dependencies.sh
+#   构建单个: bash build-docker-optimized.sh gateway:1.0.0
+#   构建多个: bash build-docker-optimized.sh gateway:3.0.2 order-service:3.0.5 payment-service:3.0.5
+#   自定义仓库: bash build-docker-optimized.sh gateway:1.0.0 -r myregistry.com
+# ============================================
+
+set -o pipefail  # 管道中任何命令失败都会导致脚本退出
+
+# 颜色定义
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+CYAN='\033[0;36m'
+NC='\033[0m'  # No Color
+
+# 全局构建参数(同一次构建中所有镜像共享)
+BUILD_NUMBER=$(date +%Y%m%d%H%M%S)
+GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null ; echo "unknown")
+
+# 函数:打印颜色信息
+log_info() {
+    echo -e "${BLUE}[INFO]${NC} $1"
+}
+
+log_success() {
+    echo -e "${GREEN}[✓]${NC} $1"
+}
+
+log_error() {
+    echo -e "${RED}[✗]${NC} $1" >&2
+}
+
+log_warn() {
+    echo -e "${YELLOW}[!]${NC} $1"
+}
+
+log_title() {
+    echo -e "${CYAN}$1${NC}"
+}
+
+# 函数:显示使用帮助
+show_help() {
+    cat << EOF
+用法: $0 [OPTIONS] SERVICE:TAG [SERVICE:TAG] ...
+
+服务简称:
+  gateway         - shop-recycle-gateway 网关服务
+  order           - shop-recycle-order-service 订单服务
+  order-service   - shop-recycle-order-service (别名)
+  payment         - shop-recycle-payment-service 支付服务
+  payment-service - shop-recycle-payment-service (别名)
+
+全局选项:
+  -h, --help              显示此帮助信息
+  -r, --registry ADDR     镜像仓库地址 (默认: harbor.stardance/shoprecycle)
+  --no-cache              构建时不使用缓存
+  --push                  构建完成后自动推送到镜像仓库
+
+示例:
+  # 构建单个服务
+  bash $0 gateway:1.0.0
+  
+  # 构建多个服务(依次进行)
+  bash $0 gateway:3.0.2 order-service:3.0.5 payment-service:3.0.5
+  
+  # 自定义镜像仓库
+  bash $0 gateway:1.0.0 -r myregistry.com
+  
+  # 禁用缓存并推送
+  bash $0 gateway:1.0.0 --no-cache --push
+
+EOF
+}
+
+# 参数处理
+REGISTRY="harbor.stardance/shoprecycle"
+NO_CACHE=""
+PUSH_IMAGE=false
+BUILD_TARGETS=()
+
+# 解析参数
+while [[ $# -gt 0 ]]; do
+    case $1 in
+        -h|--help)
+            show_help
+            exit 0
+            ;;
+        -r|--registry)
+            REGISTRY="$2"
+            shift 2
+            ;;
+        --no-cache)
+            NO_CACHE="--no-cache"
+            shift
+            ;;
+        --push)
+            PUSH_IMAGE=true
+            shift
+            ;;
+        *)
+            # 服务:标签 格式的参数
+            BUILD_TARGETS+=("$1")
+            shift
+            ;;
+    esac
+done
+
+# 验证必要参数
+if [ ${#BUILD_TARGETS[@]} -eq 0 ]; then
+    log_error "缺少构建目标"
+    echo ""
+    show_help
+    exit 1
+fi
+
+# 函数:解析 service:tag 格式
+parse_service_tag() {
+    local input="$1"
+    
+    if [[ ! "$input" =~ : ]]; then
+        log_error "格式错误: $input (应为 service:tag 格式)"
+        return 1
+    fi
+    
+    local service="${input%%:*}"
+    local tag="${input##*:}"
+    
+    # 映射服务名称
+    local dockerfile=""
+    local image_name=""
+    
+    case "$service" in
+        gateway)
+            dockerfile="shop-recycle-gateway/Dockerfile.optimized"
+            image_name="$REGISTRY/shop-recycle-gateway:$tag"
+            ;;
+        order|order-service)
+            dockerfile="shop-recycle-order-service/Dockerfile.optimized"
+            image_name="$REGISTRY/shop-recycle-order-service:$tag"
+            ;;
+        payment|payment-service)
+            dockerfile="shop-recycle-payment-service/Dockerfile.optimized"
+            image_name="$REGISTRY/shop-recycle-payment-service:$tag"
+            ;;
+        *)
+            log_error "未知服务: $service"
+            return 1
+            ;;
+    esac
+    
+    # 输出为 json 格式便于后续处理
+    echo "{\"service\":\"$service\",\"tag\":\"$tag\",\"dockerfile\":\"$dockerfile\",\"image\":\"$image_name\"}"
+}
+
+# 函数:构建单个镜像
+build_image() {
+    local service="$1"
+    local tag="$2"
+    local dockerfile="$3"
+    local image_name="$4"
+    
+    # 检查 Dockerfile 是否存在
+    if [ ! -f "$dockerfile" ]; then
+        log_error "Dockerfile 不存在: $dockerfile"
+        return 1
+    fi
+    
+    local start_time=$(date +%s)
+    
+    # 打印构建信息
+    echo ""
+    log_title "════════════════════════════════════════════════════════════"
+    log_title "Docker 镜像构建"
+    log_title "════════════════════════════════════════════════════════════"
+    log_info "服务:      $service"
+    log_info "镜像标签:  $tag"
+    log_info "仓库地址:  $REGISTRY"
+    log_info "镜像名称:  $image_name"
+    log_info "Git 提交:  $GIT_COMMIT"
+    log_info "构建号:    $BUILD_NUMBER"
+    [ -n "$NO_CACHE" ] && log_warn "禁用构建缓存"
+    echo ""
+    
+    log_info "开始构建镜像..."
+    echo ""
+    
+    # 执行 Docker 构建(传递全局构建参数)
+    if docker build $NO_CACHE \
+        --build-arg BUILD_NUMBER="$BUILD_NUMBER" \
+        --build-arg GIT_COMMIT="$GIT_COMMIT" \
+        -t "$image_name" \
+        -f "$dockerfile" \
+        .; then
+        
+        local end_time=$(date +%s)
+        local duration=$((end_time - start_time))
+        local minutes=$((duration / 60))
+        local seconds=$((duration % 60))
+        
+        echo ""
+        log_success "════════════════════════════════════════════════════════════"
+        log_success "构建完成!"
+        log_success "════════════════════════════════════════════════════════════"
+        log_success "用时: ${minutes}分${seconds}秒"
+        echo ""
+        
+        # 显示镜像信息
+        log_info "镜像详细信息:"
+        docker images "$image_name" --no-trunc
+        echo ""
+        
+        # 获取镜像大小
+        local image_size=$(docker images --format "{{.Size}}" "$image_name")
+        log_info "镜像大小: $image_size"
+        
+        # 推送镜像
+        if [ "$PUSH_IMAGE" = true ]; then
+            echo ""
+            log_info "准备推送镜像到仓库: $REGISTRY"
+            if docker push "$image_name"; then
+                log_success "镜像推送成功!"
+            else
+                log_error "镜像推送失败"
+                return 1
+            fi
+        fi
+        
+        return 0
+    else
+        local end_time=$(date +%s)
+        local duration=$((end_time - start_time))
+        local minutes=$((duration / 60))
+        local seconds=$((duration % 60))
+        
+        echo ""
+        log_error "════════════════════════════════════════════════════════════"
+        log_error "构建失败!用时: ${minutes}分${seconds}秒"
+        log_error "════════════════════════════════════════════════════════════"
+        echo ""
+        log_error "调试建议:"
+        echo "  # 查看 Docker 构建日志(详细信息)"
+        echo "  docker build $NO_CACHE --build-arg BUILD_NUMBER=\"$BUILD_NUMBER\" --build-arg GIT_COMMIT=\"$GIT_COMMIT\" -t \"$image_name\" -f \"$dockerfile\" . --progress=plain"
+        echo ""
+        return 1
+    fi
+}
+
+# 主程序流程
+echo ""
+log_title "╔════════════════════════════════════════════════════════════╗"
+log_title "║         Shop Recycle Docker 批量构建工具                   ║"
+log_title "╚════════════════════════════════════════════════════════════╝"
+echo ""
+
+# 解析所有构建目标
+declare -a services
+declare -a tags
+declare -a dockerfiles
+declare -a images
+
+log_info "解析构建目标..."
+for target in "${BUILD_TARGETS[@]}"; do
+    parsed=$(parse_service_tag "$target")
+    if [ $? -ne 0 ]; then
+        log_error "无法解析构建目标: $target"
+        exit 1
+    fi
+    
+    # 从 json 中提取字段
+    service=$(echo "$parsed" | grep -o '"service":"[^"]*"' | cut -d'"' -f4)
+    tag=$(echo "$parsed" | grep -o '"tag":"[^"]*"' | cut -d'"' -f4)
+    dockerfile=$(echo "$parsed" | grep -o '"dockerfile":"[^"]*"' | cut -d'"' -f4)
+    image=$(echo "$parsed" | grep -o '"image":"[^"]*"' | cut -d'"' -f4)
+    
+    services+=("$service")
+    tags+=("$tag")
+    dockerfiles+=("$dockerfile")
+    images+=("$image")
+    
+    log_success "$target"
+done
+
+echo ""
+log_info "将按顺序构建 ${#BUILD_TARGETS[@]} 个镜像"
+log_info "全局构建号: $BUILD_NUMBER"
+log_info "全局 Git 提交: $GIT_COMMIT"
+
+# 检查 git 仓库状态
+if [ -z "$(git status --porcelain 2>/dev/null)" ]; then
+    log_success "Git 工作目录干净"
+else
+    log_warn "Git 工作目录有未提交的更改"
+fi
+
+echo ""
+
+# 依次构建每个镜像
+failed_builds=()
+successful_builds=()
+
+for i in "${!services[@]}"; do
+    echo ""
+    log_title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+    log_title "进度: $((i+1))/${#BUILD_TARGETS[@]} - ${BUILD_TARGETS[$i]}"
+    log_title "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+    
+    if build_image "${services[$i]}" "${tags[$i]}" "${dockerfiles[$i]}" "${images[$i]}"; then
+        successful_builds+=("${BUILD_TARGETS[$i]}")
+    else
+        failed_builds+=("${BUILD_TARGETS[$i]}")
+        log_error "构建失败: ${BUILD_TARGETS[$i]}"
+        exit 1
+    fi
+done
+
+# 汇总报告
+echo ""
+echo ""
+log_title "╔════════════════════════════════════════════════════════════╗"
+log_title "║                     构建汇总                               ║"
+log_title "╚════════════════════════════════════════════════════════════╝"
+echo ""
+
+log_success "成功构建 ${#successful_builds[@]} 个镜像:"
+for build in "${successful_builds[@]}"; do
+    echo "  ✓ $build"
+done
+
+if [ ${#failed_builds[@]} -gt 0 ]; then
+    echo ""
+    log_error "失败 ${#failed_builds[@]} 个:"
+    for build in "${failed_builds[@]}"; do
+        echo "  ✗ $build"
+    done
+fi
+
+echo ""
+log_info "════════════════════════════════════════════════════════════"
+log_info "构建信息:"
+log_info "════════════════════════════════════════════════════════════"
+log_info "构建号:    $BUILD_NUMBER"
+log_info "Git 提交: $GIT_COMMIT"
+echo ""
+log_info "下一步操作:"
+log_info "════════════════════════════════════════════════════════════"
+echo "  # 查看镜像列表"
+echo "  docker images | grep harbor.stardance/shoprecycle"
+echo ""
+echo "  # 运行容器"
+echo "  docker run -d -p 8080:8080 --name gateway-container \\"
+echo "    harbor.stardance/shoprecycle/shop-recycle-gateway:3.0.2"
+echo ""
+if [ "$PUSH_IMAGE" = false ]; then
+    echo "  # 推送所有镜像到仓库"
+    for image in "${images[@]}"; do
+        echo "  docker push $image"
+    done
+    echo ""
+fi
+echo ""
+

+ 67 - 65
k8s/helm/shop-recycle/templates/configmap-gateway.yaml

@@ -1,65 +1,67 @@
-{{- if .Values.gateway.enabled }}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "shop-recycle.fullname" . }}-gateway-config
-  labels:
-    app: {{ include "shop-recycle.fullname" . }}-gateway
-    {{- include "shop-recycle.labels" . | nindent 4 }}
-  namespace: {{ .Release.Namespace }}
-data:
-  application.yml: |
-    spring:
-      application:
-        name: shop-recycle-gateway
-      cloud:
-        gateway:
-          routes:
-            - id: order-service
-              uri: http://{{ include "shop-recycle.fullname" . }}-order-service:{{ .Values.orderService.service.port }}
-              predicates:
-                - Path=/api/order/**
-              filters:
-                - RewritePath=/api/order(?<segment>.*), /api$\{segment}
-            
-            - id: payment-service
-              uri: http://{{ include "shop-recycle.fullname" . }}-payment-service:{{ .Values.paymentService.service.port }}
-              predicates:
-                - Path=/api/payment/**
-              filters:
-                - RewritePath=/api/payment(?<segment>.*), /api$\{segment}
-            
-            - id: test-order
-              uri: http://{{ include "shop-recycle.fullname" . }}-order-service:{{ .Values.orderService.service.port }}
-              predicates:
-                - Path=/api/test/order/**
-              filters:
-                - RewritePath=/api/test/order(?<segment>.*), /test$\{segment}
-            
-            - id: test-payment
-              uri: http://{{ include "shop-recycle.fullname" . }}-payment-service:{{ .Values.paymentService.service.port }}
-              predicates:
-                - Path=/api/test/payment/**
-              filters:
-                - RewritePath=/api/test/payment(?<segment>.*), /test$\{segment}
-    
-    management:
-      endpoints:
-        web:
-          exposure:
-            include: health,info,metrics
-      metrics:
-        export:
-          prometheus:
-            enabled: true
-      endpoint:
-        health:
-          show-details: when-authorized
-    
-    logging:
-      level:
-        root: {{ .Values.logging.level }}
-        com.shop.recycle: DEBUG
-      pattern:
-        console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
-{{- end }}
+{{- if .Values.gateway.enabled }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "shop-recycle.fullname" . }}-gateway-config
+  labels:
+    app: {{ include "shop-recycle.fullname" . }}-gateway
+    {{- include "shop-recycle.labels" . | nindent 4 }}
+  namespace: {{ .Release.Namespace }}
+data:
+  application.yml: |
+    spring:
+      main:
+        web-application-type: reactive
+      application:
+        name: shop-recycle-gateway
+      cloud:
+        gateway:
+          routes:
+            - id: order-service
+              uri: http://{{ include "shop-recycle.fullname" . }}-order-service:{{ .Values.orderService.service.port }}
+              predicates:
+                - Path=/api/order/**
+              filters:
+                - RewritePath=/api/order(?<segment>.*), /api$\{segment}
+            
+            - id: payment-service
+              uri: http://{{ include "shop-recycle.fullname" . }}-payment-service:{{ .Values.paymentService.service.port }}
+              predicates:
+                - Path=/api/payment/**
+              filters:
+                - RewritePath=/api/payment(?<segment>.*), /api$\{segment}
+            
+            - id: test-order
+              uri: http://{{ include "shop-recycle.fullname" . }}-order-service:{{ .Values.orderService.service.port }}
+              predicates:
+                - Path=/api/test/order/**
+              filters:
+                - RewritePath=/api/test/order(?<segment>.*), /test$\{segment}
+            
+            - id: test-payment
+              uri: http://{{ include "shop-recycle.fullname" . }}-payment-service:{{ .Values.paymentService.service.port }}
+              predicates:
+                - Path=/api/test/payment/**
+              filters:
+                - RewritePath=/api/test/payment(?<segment>.*), /test$\{segment}
+    
+    management:
+      endpoints:
+        web:
+          exposure:
+            include: health,info,metrics
+      metrics:
+        export:
+          prometheus:
+            enabled: true
+      endpoint:
+        health:
+          show-details: when-authorized
+    
+    logging:
+      level:
+        root: {{ .Values.logging.level }}
+        com.shop.recycle: DEBUG
+      pattern:
+        console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
+{{- end }}

+ 6 - 5
k8s/helm/shop-recycle/templates/deployment-gateway.yaml

@@ -43,12 +43,8 @@ spec:
       
       containers:
         - name: gateway
-          image: "{{ .Values.image.registry }}/{{ .Values.image.namespace }}/{{ .Values.gateway.image.name }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+          image: "{{ .Values.image.registry }}/{{ .Values.image.namespace }}/{{ .Values.gateway.image.name }}:{{ .Values.gateway.image.tag }}"
           imagePullPolicy: {{ .Values.image.pullPolicy }}
-          command:
-            - sh
-            - -c
-            - java ${JAVA_OPTS} -jar /app/gateway.jar
           
           ports:
             - name: http
@@ -70,6 +66,11 @@ spec:
               value: "{{ $value }}"
             {{- end }}
           
+          {{- if .Values.gateway.startupProbe }}
+          startupProbe:
+            {{- toYaml .Values.gateway.startupProbe | nindent 12 }}
+          {{- end }}
+
           {{- if .Values.gateway.livenessProbe }}
           livenessProbe:
             {{- toYaml .Values.gateway.livenessProbe | nindent 12 }}

+ 6 - 5
k8s/helm/shop-recycle/templates/deployment-order-service.yaml

@@ -43,12 +43,8 @@ spec:
       
       containers:
         - name: order-service
-          image: "{{ .Values.image.registry }}/{{ .Values.image.namespace }}/{{ .Values.orderService.image.name }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+          image: "{{ .Values.image.registry }}/{{ .Values.image.namespace }}/{{ .Values.orderService.image.name }}:{{ .Values.orderService.image.tag }}"
           imagePullPolicy: {{ .Values.image.pullPolicy }}
-          command:
-            - sh
-            - -c
-            - java ${JAVA_OPTS} -jar /app/order-service.jar
           
           ports:
             - name: http
@@ -67,6 +63,11 @@ spec:
               value: "{{ $value }}"
             {{- end }}
           
+          {{- if .Values.orderService.startupProbe }}
+          startupProbe:
+            {{- toYaml .Values.orderService.startupProbe | nindent 12 }}
+          {{- end }}
+
           {{- if .Values.orderService.livenessProbe }}
           livenessProbe:
             {{- toYaml .Values.orderService.livenessProbe | nindent 12 }}

+ 6 - 5
k8s/helm/shop-recycle/templates/deployment-payment-service.yaml

@@ -43,12 +43,8 @@ spec:
       
       containers:
         - name: payment-service
-          image: "{{ .Values.image.registry }}/{{ .Values.image.namespace }}/{{ .Values.paymentService.image.name }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+          image: "{{ .Values.image.registry }}/{{ .Values.image.namespace }}/{{ .Values.paymentService.image.name }}:{{ .Values.paymentService.image.tag }}"
           imagePullPolicy: {{ .Values.image.pullPolicy }}
-          command:
-            - sh
-            - -c
-            - java ${JAVA_OPTS} -jar /app/payment-service.jar
           
           ports:
             - name: http
@@ -67,6 +63,11 @@ spec:
               value: "{{ $value }}"
             {{- end }}
           
+          {{- if .Values.paymentService.startupProbe }}
+          startupProbe:
+            {{- toYaml .Values.paymentService.startupProbe | nindent 12 }}
+          {{- end }}
+
           {{- if .Values.paymentService.livenessProbe }}
           livenessProbe:
             {{- toYaml .Values.paymentService.livenessProbe | nindent 12 }}

+ 366 - 356
k8s/helm/shop-recycle/values.yaml

@@ -1,356 +1,366 @@
-# ==========================================
-# Helm Values - shop-recycle
-# 全局配置(所有环境共享)
-# ==========================================
-
-# 全局配置
-global:
-  # 镜像仓库认证(若启用,Helm 自动生成 imagePullSecret)
-  registry:
-    createSecret: true  # 设为 false 则不创建 secret,使用已有的
-    username: "admin"        # harbor.stardance 用户名
-    password: "Harbor12345"        # harbor.stardance 密码
-    email: "ops@example.com"
-  
-  # 若 registry.createSecret=false,则指定已有的 secret 名称
-  imagePullSecrets: []
-  # - name: reg-cred
-  
-# 副本数
-replicaCount: 1
-
-# 镜像配置
-image:
-  registry: harbor.stardance
-  namespace: shoprecycle
-  pullPolicy: IfNotPresent
-  tag: "3.0.0"
-  # tag由Jenkins Pipeline动态注入(--set image.tag=xxx)
-
-# 环境名称(由Pipeline动态注入)
-environment: dev
-
-# ==========================================
-# Gateway (API网关)
-# ==========================================
-gateway:
-  enabled: true
-  replicaCount: 1
-  
-  image:
-    name: gateway
-    tag: "3.0.5"
-  
-  port: 8080
-  containerPort: 8080
-  protocol: TCP
-  
-  resources:
-    requests:
-      memory: "256Mi"
-      cpu: "250m"
-    limits:
-      memory: "512Mi"
-      cpu: "500m"
-  
-  # JVM参数
-  javaOpts: "-Xms256m -Xmx512m -XX:+UseG1GC"
-  
-  # Spring Profiles
-  springProfiles: "kubernetes"
-  
-  # 健康检查
-  livenessProbe:
-    httpGet:
-      path: /health
-      port: 8080
-    initialDelaySeconds: 30
-    periodSeconds: 10
-    timeoutSeconds: 5
-    failureThreshold: 3
-  
-  readinessProbe:
-    httpGet:
-      path: /health
-      port: 8080
-    initialDelaySeconds: 20
-    periodSeconds: 5
-    timeoutSeconds: 3
-    failureThreshold: 3
-  
-  # 服务配置
-  service:
-    type: ClusterIP
-    port: 8080
-    targetPort: 8080
-    annotations: {}
-  
-  # 入口配置
-  ingress:
-    enabled: false
-    className: "nginx"
-    annotations:
-      cert-manager.io/cluster-issuer: "letsencrypt-prod"
-    hosts:
-      - host: "dev.jxfxtd.com"
-        paths:
-          - path: /
-            pathType: Prefix
-    tls:
-      - secretName: gateway-tls
-        hosts:
-          - "dev.jxfxtd.com"
-  
-  # 环境变量
-  env:
-    SPRING_CLOUD_CONFIG_ENABLED: "true"
-    LOGGING_LEVEL_ROOT: "INFO"
-  
-  # ConfigMap数据
-  configMap:
-    application.yml: |
-      spring:
-        cloud:
-          gateway:
-            routes:
-              - id: order-service
-                uri: http://shop-recycle-order-service:8081
-                predicates:
-                  - Path=/api/order/**
-              - id: payment-service
-                uri: http://shop-recycle-payment-service:8082
-                predicates:
-                  - Path=/api/payment/**
-              - id: test-order
-                uri: http://shop-recycle-order-service:8081
-                predicates:
-                  - Path=/api/test/**
-              - id: test-payment
-                uri: http://shop-recycle-payment-service:8082
-                predicates:
-                  - Path=/api/test/**
-      management:
-        endpoints:
-          web:
-            exposure:
-              include: health,info
-
-# ==========================================
-# Order Service (订单服务)
-# ==========================================
-orderService:
-  enabled: true
-  replicaCount: 1
-  
-  image:
-    name: order-service
-    tag: "3.0.5"
-  
-  port: 8081
-  containerPort: 8081
-  protocol: TCP
-  
-  resources:
-    requests:
-      memory: "256Mi"
-      cpu: "250m"
-    limits:
-      memory: "512Mi"
-      cpu: "500m"
-  
-  javaOpts: "-Xms256m -Xmx512m -XX:+UseG1GC"
-  springProfiles: "kubernetes"
-  
-  livenessProbe:
-    httpGet:
-      path: /health
-      port: 8081
-    initialDelaySeconds: 30
-    periodSeconds: 10
-    timeoutSeconds: 5
-    failureThreshold: 3
-  
-  readinessProbe:
-    httpGet:
-      path: /health
-      port: 8081
-    initialDelaySeconds: 20
-    periodSeconds: 5
-    timeoutSeconds: 3
-    failureThreshold: 3
-  
-  service:
-    type: ClusterIP
-    port: 8081
-    targetPort: 8081
-    annotations: {}
-  
-  env:
-    SPRING_CLOUD_CONFIG_ENABLED: "true"
-    LOGGING_LEVEL_ROOT: "INFO"
-
-# ==========================================
-# Payment Service (支付服务)
-# ==========================================
-paymentService:
-  enabled: true
-  replicaCount: 1
-  
-  image:
-    name: payment-service
-    tag: "3.0.5"
-  
-  port: 8082
-  containerPort: 8082
-  protocol: TCP
-  
-  resources:
-    requests:
-      memory: "256Mi"
-      cpu: "250m"
-    limits:
-      memory: "512Mi"
-      cpu: "500m"
-  
-  javaOpts: "-Xms256m -Xmx512m -XX:+UseG1GC"
-  springProfiles: "kubernetes"
-  
-  livenessProbe:
-    httpGet:
-      path: /health
-      port: 8082
-    initialDelaySeconds: 30
-    periodSeconds: 10
-    timeoutSeconds: 5
-    failureThreshold: 3
-  
-  readinessProbe:
-    httpGet:
-      path: /health
-      port: 8082
-    initialDelaySeconds: 20
-    periodSeconds: 5
-    timeoutSeconds: 3
-    failureThreshold: 3
-  
-  service:
-    type: ClusterIP
-    port: 8082
-    targetPort: 8082
-    annotations: {}
-  
-  env:
-    SPRING_CLOUD_CONFIG_ENABLED: "true"
-    LOGGING_LEVEL_ROOT: "INFO"
-
-# ==========================================
-# Web Frontend (前端应用)
-# ==========================================
-webFrontend:
-  enabled: true
-  replicaCount: 1
-  
-  image:
-    name: web
-    tag: "3.0.0"
-  
-  port: 80
-  containerPort: 80
-  protocol: TCP
-  
-  resources:
-    requests:
-      memory: "128Mi"
-      cpu: "100m"
-    limits:
-      memory: "256Mi"
-      cpu: "500m"
-  
-  livenessProbe:
-    httpGet:
-      path: /health
-      port: 80
-    initialDelaySeconds: 10
-    periodSeconds: 10
-    timeoutSeconds: 5
-    failureThreshold: 3
-  
-  readinessProbe:
-    httpGet:
-      path: /
-      port: 80
-    initialDelaySeconds: 5
-    periodSeconds: 5
-    timeoutSeconds: 3
-    failureThreshold: 3
-  
-  service:
-    type: ClusterIP
-    port: 80
-    targetPort: 80
-    annotations: {}
-  
-  ingress:
-    enabled: true
-    className: "nginx"
-    annotations:
-      cert-manager.io/cluster-issuer: "letsencrypt-prod"
-    hosts:
-      - host: "dev.jxfxtd.com"
-        paths:
-          - path: /
-            pathType: Prefix
-    tls:
-      - secretName: web-tls
-        hosts:
-          - "dev.jxfxtd.com"
-  
-  env:
-    VUE_APP_API_BASE: "http://shop-recycle-gateway:8080"
-    LOGGING_LEVEL: "info"
-
-# ==========================================
-# 网络策略
-# ==========================================
-networkPolicy:
-  enabled: false
-  policyTypes:
-    - Ingress
-    - Egress
-
-# ==========================================
-# Pod安全策略
-# ==========================================
-podSecurityPolicy:
-  enabled: false
-
-# ==========================================
-# RBAC配置
-# ==========================================
-rbac:
-  create: true
-  # 指定已有的ServiceAccount
-  serviceAccountName: ""
-
-# ==========================================
-# 节点亲和性与污点容限
-# ==========================================
-affinity: {}
-
-tolerations: []
-
-# ==========================================
-# 监控和日志
-# ==========================================
-monitoring:
-  enabled: false
-  # Prometheus ServiceMonitor
-  serviceMonitor:
-    enabled: false
-    interval: 30s
-
-logging:
-  # 日志级别
-  level: INFO
-  # 日志输出格式
-  format: json
+# ==========================================
+# Helm Values - shop-recycle
+# 全局配置(所有环境共享)
+# ==========================================
+
+# 全局配置
+global:
+  # 镜像仓库认证(若启用,Helm 自动生成 imagePullSecret)
+  registry:
+    createSecret: true  # 设为 false 则不创建 secret,使用已有的
+    username: "admin"        # harbor.stardance 用户名
+    password: "Harbor12345"        # harbor.stardance 密码
+    email: "ops@example.com"
+  
+  # 若 registry.createSecret=false,则指定已有的 secret 名称
+  imagePullSecrets: []
+  # - name: reg-cred
+  
+# 副本数
+replicaCount: 1
+
+# 镜像配置
+image:
+  registry: harbor.stardance
+  namespace: shoprecycle
+  pullPolicy: IfNotPresent
+  tag: "3.0.0"
+  # tag由Jenkins Pipeline动态注入(--set image.tag=xxx)
+
+# 环境名称(由Pipeline动态注入)
+environment: dev
+
+# ==========================================
+# Gateway (API网关)
+# ==========================================
+gateway:
+  enabled: true
+  replicaCount: 1
+  
+  image:
+    name: gateway
+    tag: "3.0.6"
+  
+  port: 8080
+  containerPort: 8080
+  protocol: TCP
+  
+  resources:
+    requests:
+      memory: "256Mi"
+      cpu: "250m"
+    limits:
+      memory: "512Mi"
+      cpu: "500m"
+  
+  # JVM参数
+  javaOpts: "-Xms256m -Xmx512m -XX:+UseG1GC"
+  
+  # Spring Profiles
+  springProfiles: "kubernetes"
+  
+  # 健康检查
+  livenessProbe:
+    httpGet:
+      path: /health
+      port: 8080
+    initialDelaySeconds: 30
+    periodSeconds: 10
+    timeoutSeconds: 5
+    failureThreshold: 3
+  
+  readinessProbe:
+    httpGet:
+      path: /health
+      port: 8080
+    initialDelaySeconds: 20
+    periodSeconds: 5
+    timeoutSeconds: 3
+    failureThreshold: 3
+  
+  # 服务配置
+  # 启动探针 - 给 Java 应用充分的启动时间(5分钟才开始检查)
+  startupProbe:
+    httpGet:
+      path: /health
+      port: 8080
+    initialDelaySeconds: 300
+    periodSeconds: 10
+    timeoutSeconds: 5
+    failureThreshold: 60
+
+  service:
+    type: ClusterIP
+    port: 8080
+    targetPort: 8080
+    annotations: {}
+  
+  # 入口配置
+  ingress:
+    enabled: false
+    className: "nginx"
+    annotations:
+      cert-manager.io/cluster-issuer: "letsencrypt-prod"
+    hosts:
+      - host: "dev.jxfxtd.com"
+        paths:
+          - path: /
+            pathType: Prefix
+    tls:
+      - secretName: gateway-tls
+        hosts:
+          - "dev.jxfxtd.com"
+  
+  # 环境变量
+  env:
+    SPRING_CLOUD_CONFIG_ENABLED: "true"
+    LOGGING_LEVEL_ROOT: "INFO"
+  
+  # ConfigMap数据
+  configMap:
+    application.yml: |
+      spring:
+        cloud:
+          gateway:
+            routes:
+              - id: order-service
+                uri: http://shop-recycle-order-service:8081
+                predicates:
+                  - Path=/api/order/**
+              - id: payment-service
+                uri: http://shop-recycle-payment-service:8082
+                predicates:
+                  - Path=/api/payment/**
+              - id: test-order
+                uri: http://shop-recycle-order-service:8081
+                predicates:
+                  - Path=/api/test/**
+              - id: test-payment
+                uri: http://shop-recycle-payment-service:8082
+                predicates:
+                  - Path=/api/test/**
+      management:
+        endpoints:
+          web:
+            exposure:
+              include: health,info
+
+# ==========================================
+# Order Service (订单服务)
+# ==========================================
+orderService:
+  enabled: true
+  replicaCount: 1
+  
+  image:
+    name: order-service
+    tag: "3.0.6"
+  
+  port: 8081
+  containerPort: 8081
+  protocol: TCP
+  
+  resources:
+    requests:
+      memory: "256Mi"
+      cpu: "250m"
+    limits:
+      memory: "512Mi"
+      cpu: "500m"
+  
+  javaOpts: "-Xms256m -Xmx512m -XX:+UseG1GC"
+  springProfiles: "kubernetes"
+  
+  livenessProbe:
+    httpGet:
+      path: /health
+      port: 8081
+    initialDelaySeconds: 30
+    periodSeconds: 10
+    timeoutSeconds: 5
+    failureThreshold: 3
+  
+  readinessProbe:
+    httpGet:
+      path: /health
+      port: 8081
+    initialDelaySeconds: 20
+    periodSeconds: 5
+    timeoutSeconds: 3
+    failureThreshold: 3
+  
+  service:
+    type: ClusterIP
+    port: 8081
+    targetPort: 8081
+    annotations: {}
+  
+  env:
+    SPRING_CLOUD_CONFIG_ENABLED: "true"
+    LOGGING_LEVEL_ROOT: "INFO"
+
+# ==========================================
+# Payment Service (支付服务)
+# ==========================================
+paymentService:
+  enabled: true
+  replicaCount: 1
+  
+  image:
+    name: payment-service
+    tag: "3.0.6"
+  
+  port: 8082
+  containerPort: 8082
+  protocol: TCP
+  
+  resources:
+    requests:
+      memory: "256Mi"
+      cpu: "250m"
+    limits:
+      memory: "512Mi"
+      cpu: "500m"
+  
+  javaOpts: "-Xms256m -Xmx512m -XX:+UseG1GC"
+  springProfiles: "kubernetes"
+  
+  livenessProbe:
+    httpGet:
+      path: /health
+      port: 8082
+    initialDelaySeconds: 30
+    periodSeconds: 10
+    timeoutSeconds: 5
+    failureThreshold: 3
+  
+  readinessProbe:
+    httpGet:
+      path: /health
+      port: 8082
+    initialDelaySeconds: 20
+    periodSeconds: 5
+    timeoutSeconds: 3
+    failureThreshold: 3
+  
+  service:
+    type: ClusterIP
+    port: 8082
+    targetPort: 8082
+    annotations: {}
+  
+  env:
+    SPRING_CLOUD_CONFIG_ENABLED: "true"
+    LOGGING_LEVEL_ROOT: "INFO"
+
+# ==========================================
+# Web Frontend (前端应用)
+# ==========================================
+webFrontend:
+  enabled: true
+  replicaCount: 1
+  
+  image:
+    name: web
+    tag: "3.0.0"
+  
+  port: 80
+  containerPort: 80
+  protocol: TCP
+  
+  resources:
+    requests:
+      memory: "128Mi"
+      cpu: "100m"
+    limits:
+      memory: "256Mi"
+      cpu: "500m"
+  
+  livenessProbe:
+    httpGet:
+      path: /health
+      port: 80
+    initialDelaySeconds: 10
+    periodSeconds: 10
+    timeoutSeconds: 5
+    failureThreshold: 3
+  
+  readinessProbe:
+    httpGet:
+      path: /
+      port: 80
+    initialDelaySeconds: 5
+    periodSeconds: 5
+    timeoutSeconds: 3
+    failureThreshold: 3
+  
+  service:
+    type: ClusterIP
+    port: 80
+    targetPort: 80
+    annotations: {}
+  
+  ingress:
+    enabled: true
+    className: "nginx"
+    annotations:
+      cert-manager.io/cluster-issuer: "letsencrypt-prod"
+    hosts:
+      - host: "dev.jxfxtd.com"
+        paths:
+          - path: /
+            pathType: Prefix
+    tls:
+      - secretName: web-tls
+        hosts:
+          - "dev.jxfxtd.com"
+  
+  env:
+    VUE_APP_API_BASE: "http://shop-recycle-gateway:8080"
+    LOGGING_LEVEL: "info"
+
+# ==========================================
+# 网络策略
+# ==========================================
+networkPolicy:
+  enabled: false
+  policyTypes:
+    - Ingress
+    - Egress
+
+# ==========================================
+# Pod安全策略
+# ==========================================
+podSecurityPolicy:
+  enabled: false
+
+# ==========================================
+# RBAC配置
+# ==========================================
+rbac:
+  create: true
+  # 指定已有的ServiceAccount
+  serviceAccountName: ""
+
+# ==========================================
+# 节点亲和性与污点容限
+# ==========================================
+affinity: {}
+
+tolerations: []
+
+# ==========================================
+# 监控和日志
+# ==========================================
+monitoring:
+  enabled: false
+  # Prometheus ServiceMonitor
+  serviceMonitor:
+    enabled: false
+    interval: 30s
+
+logging:
+  # 日志级别
+  level: INFO
+  # 日志输出格式
+  format: json