导购APP容器化CI/CD流程:Jenkins在返利系统持续部署中的实践

导购APP容器化CI/CD流程:Jenkins在返利系统持续部署中的实践

大家好,我是省赚客APP研发者阿宝!

在聚娃科技省赚客返利系统的日常迭代中,我们面临多环境(dev/test/staging/prod)、多微服务(用户中心、订单核销、返现引擎等)的高频发布需求。为提升交付效率与系统稳定性,我们基于Jenkins构建了一套完整的容器化CI/CD流水线,结合Docker、Helm与Kubernetes,实现从代码提交到生产部署的自动化闭环。

整体CI/CD架构

我们的流水线分为四个阶段:

  1. 代码检出与静态检查:Git触发 → SonarQube扫描;
  2. 镜像构建与推送:Maven编译 → Docker Build → 推送至Harbor;
  3. Helm Chart版本管理:动态生成values.yaml,打Tag并推送到Chart仓库;
  4. K8s滚动部署:通过kubectl或ArgoCD应用新版本。

所有配置以Jenkinsfile声明式Pipeline实现,确保流程可复用、可审计。

Jenkinsfile核心实现

以下为返利核心服务cashback-service的Jenkinsfile片段:

groovy 复制代码
pipeline {
    agent any
    environment {
        APP_NAME = 'cashback-service'
        REGISTRY = 'harbor.juwatech.cn'
        CHART_REPO = 'https://charts.juwatech.cn'
        NAMESPACE = "${params.ENV == 'prod' ? 'prod' : 'staging'}"
    }
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        stage('Build & Test') {
            steps {
                sh 'mvn clean compile -DskipTests'
                sh 'mvn test -Dtest=juwatech.cn.cashback.*Test'
            }
        }
        stage('Sonar Scan') {
            steps {
                withSonarQubeEnv('sonar-server') {
                    sh 'mvn sonar:sonar -Dsonar.projectKey=${APP_NAME}'
                }
            }
        }
        stage('Build Docker Image') {
            steps {
                script {
                    def imageTag = "${REGISTRY}/juwatech/${APP_NAME}:${BUILD_NUMBER}"
                    sh "docker build -t ${imageTag} ."
                    sh "docker push ${imageTag}"
                    env.IMAGE_TAG = imageTag
                }
            }
        }
        stage('Deploy to K8s') {
            steps {
                sh """
                    helm upgrade --install ${APP_NAME} \\
                        --repo ${CHART_REPO} cashback-chart \\
                        --namespace ${NAMESPACE} \\
                        --set image.repository=${REGISTRY}/juwatech/${APP_NAME} \\
                        --set image.tag=${BUILD_NUMBER} \\
                        --set replicaCount=${params.REPLICAS ?: 2}
                """
            }
        }
    }
}

Dockerfile与Java工程集成

项目根目录下的Dockerfile采用多阶段构建,仅打包最终JAR:

dockerfile 复制代码
# Stage 1: 编译
FROM maven:3.8.6-jdk-11 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# Stage 2: 运行
FROM openjdk:11-jre-slim
LABEL maintainer="dev@juwatech.cn"
COPY --from=builder /app/target/cashback-service-*.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

其中,主启动类位于juwatech.cn.cashback.CashbackApplication:

java 复制代码
package juwatech.cn.cashback;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CashbackApplication {
    public static void main(String[] args) {
        SpringApplication.run(CashbackApplication.class, args);
    }
}

Helm Chart结构设计

每个服务对应独立Chart,目录结构如下:

复制代码
cashback-chart/
├── Chart.yaml
├── values.yaml
└── templates/
    ├── deployment.yaml
    └── service.yaml

values.yaml支持动态覆盖:

yaml 复制代码
replicaCount: 2
image:
  repository: harbor.juwatech.cn/juwatech/cashback-service
  tag: "latest"
  pullPolicy: IfNotPresent
env:
  JAVA_OPTS: "-Xmx512m -Xms256m"

在CI中通过--set参数注入构建号,确保版本可追溯。

权限与安全控制

为避免Jenkins过度权限,我们采用最小化原则:

  • Jenkins Agent运行于独立Namespace;
  • 使用K8s ServiceAccount绑定RBAC角色,仅允许操作指定命名空间;
  • Harbor镜像仓库启用项目级权限,Jenkins凭据通过K8s Secret挂载。

Jenkins凭据配置示例(credentials binding插件):

groovy 复制代码
stage('Push to Harbor') {
    environment {
        HARBOR_USER = credentials('harbor-robot-account')
    }
    steps {
        sh "docker login ${REGISTRY} -u ${HARBOR_USER_USR} -p ${HARBOR_USER_PSW}"
        // ... push
    }
}

回滚与蓝绿发布支持

当生产环境出现异常,可通过Jenkins快速回滚至前一版本:

groovy 复制代码
stage('Rollback') {
    when { 
        expression { params.ROLLBACK == true } 
    }
    steps {
        sh """
            PREV_TAG=$(helm history ${APP_NAME} -n ${NAMESPACE} | awk 'NR==3 {print $2}')
            helm rollback ${APP_NAME} \$PREV_TAG -n ${NAMESPACE}
        """
    }
}

对于关键服务,我们正在试点蓝绿发布,通过Istio流量切分实现零 downtime 升级,后续将集成至Jenkins Pipeline。

监控与通知

每次部署完成后,自动发送结果至企业微信:

groovy 复制代码
post {
    success {
        sh 'curl -X POST -H "Content-Type: application/json" -d \'{"msgtype":"text","text":{"content":"[CI/CD] ${APP_NAME} 部署成功,版本:${BUILD_NUMBER}"}}\' ${WECHAT_WEBHOOK}'
    }
    failure {
        sh 'curl -X POST -H "Content-Type: application/json" -d \'{"msgtype":"text","text":{"content":"[CI/CD] ${APP_NAME} 部署失败!"}}\' ${WECHAT_WEBHOOK}'
    }
}

目前,该流程支撑省赚客每日30+次部署,平均交付时长从2小时缩短至8分钟,发布事故率下降90%。

本文著作权归聚娃科技省赚客app开发者团队,转载请注明出处!

相关推荐
江华森1 小时前
数据中心基础设施运维实战:概述与实验环境搭建
运维
迪菲赫尔曼1 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
by209992 小时前
Linux GCC/G++ 编译与 Makefile 构建
linux·运维·服务器·经验分享
螺丝钉tina3 小时前
[Playwright][08] Upload 模块自动化:如何设计真实业务测试用例?
运维·自动化·测试用例
迪菲赫尔曼3 小时前
【基础篇 12】把环境与源码接起来:检查 GPU,再安装服务器上的项目
运维·服务器·开发语言·人工智能·python·yolo·目标检测
cq林志炫3 小时前
两个Linux服务器之间同步文件
linux·运维·服务器
yyuuuzz4 小时前
云服务器安全组规则优先级的机制记录
运维·服务器·网络·安全·阿里云·aws
KaiwuDB4 小时前
KaiwuDB 运维实战06:数据库备份与恢复:从理论到实战
运维·数据库·时序数据库·kaiwudb
知已难寻4 小时前
01 · OpenStack的认证管理 Keystone
运维·服务器·云原生·云计算·openstack
ai_xiaogui5 小时前
私有化部署大模型实战:PanelAI 一键搭建、Token 计费与多用户隔离
运维·私有化部署·大模型部署·大模型 token 计费·api key 统一管理·多用户实例隔离·应用市场一键部署