1. 为什么选择Ruo-Yi作为CICD实践对象?
Ruo-Yi作为国内广泛使用的开源后台管理系统,采用Spring Boot+MyBatis技术栈,具有典型的企业级Java项目特征。其模块化结构(包含ry-admin、ry-system等子模块)和依赖关系复杂度,恰好能验证CICD流程对多模块项目的支持能力。我在金融行业实施微服务架构时,发现这类项目最常遇到的痛点包括:
- 本地构建成功但线上环境失败(经典问题:
mvn clean install能跑但服务器上报ClassNotFound) - 多环境配置混乱(开发/测试/生产环境的数据库连接串混在同一个application.yml里)
- 人工部署时遗漏依赖项(比如忘记更新某个jar包的SNAPSHOT版本)
以Ruo-Yi的pom.xml为例,其父子模块的依赖继承关系需要特殊处理。我曾遇到过一个案例:某团队在Jenkins上直接执行mvn package,结果生成的ry-admin.war包里缺少了ry-system模块的依赖。这就是没有理解Maven反应堆构建顺序导致的典型问题。
关键认知:CICD不是简单地把本地命令搬到服务器,而是要对构建环境、依赖解析、产物验证等环节进行标准化控制。
2. 基础设施准备:不可忽视的细节
2.1 Jenkins的"正确打开方式"
很多教程只教如何用war包启动Jenkins,但生产环境更需要考虑:
bash复制# 使用官方Docker镜像时务必挂载这些目录
docker run -d \
-v /your_path/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/local/maven:/usr/local/maven \
-p 8080:8080 jenkins/jenkins:lts
/var/run/docker.sock挂载让Jenkins能操作宿主机Docker(需考虑安全风险)- Maven本地仓库外置避免容器重启后重复下载依赖
- 实际案例:某公司因未挂载
docker.sock,导致Pipeline中所有docker命令失效
2.2 凭证管理的血泪教训
在配置Git仓库认证时,我强烈建议使用SSH密钥而非用户名密码:
- 在Jenkins凭据页面添加"SSH Username with private key"类型凭据
- 将生成的公钥添加到Gitee/GitLab的Deploy Keys
- 测试连接时常见报错处理:
log复制这往往是网络策略问题,需要检查:ERROR: Timeout after 10 minutes- 服务器能否ping通代码仓库
- 是否配置了HTTP代理(尤其在企业内网环境)
3. Pipeline核心逻辑拆解
3.1 多阶段构建设计
这是经过多个项目验证的Pipeline模板:
groovy复制pipeline {
agent any
stages {
stage('代码质量门禁') {
steps {
sh 'mvn sonar:sonar -Dsonar.projectKey=ruoyi'
timeout(time: 15, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
stage('多模块构建') {
parallel {
stage('核心模块') {
steps {
dir('ruoyi-admin') {
sh 'mvn clean package -DskipTests'
}
}
}
stage('系统模块') {
steps {
dir('ruoyi-system') {
sh 'mvn clean package -DskipTests'
}
}
}
}
}
stage('Docker镜像构建') {
steps {
script {
docker.build("ruoyi-admin:${env.BUILD_ID}", "-f ruoyi-admin/Dockerfile .")
}
}
}
}
}
关键设计点:
- 并行构建加速编译(注意各模块间依赖关系)
- SonarQube质量门禁阻断不合格代码
- BUILD_ID动态标签避免镜像版本冲突
3.2 那些容易踩的坑
-
Java版本问题:Ruo-Yi要求JDK8,但服务器可能默认是JDK11。解决方案:
groovy复制tools { jdk 'jdk8' // 需提前在Jenkins全局配置中定义 } -
文件路径陷阱:在Dockerfile中:
dockerfile复制# 错误示范(使用绝对路径) COPY /target/ruoyi-admin.jar /app.jar # 正确做法(相对构建上下文路径) COPY target/ruoyi-admin.jar /app.jar -
资源清理:Pipeline最后务必添加:
groovy复制post { always { cleanWs() // 清理工作空间 sh 'docker system prune -f' // 清理悬空镜像 } }
4. 进阶:Kubernetes集成实战
当项目需要横向扩展时,传统的单机Docker部署会面临瓶颈。这是我为Ruo-Yi设计的k8s部署方案:
4.1 编写Helm Chart
目录结构:
code复制ruoyi-chart/
├── Chart.yaml
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ingress.yaml
└── values.yaml
关键配置(deployment.yaml片段):
yaml复制containers:
- name: ruoyi
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
resources:
limits:
cpu: 1000m
memory: 1Gi
livenessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60 # 适当延长等待时间
4.2 Jenkins与k8s的对接
- 安装Kubernetes插件后,在Jenkinsfile中添加:
groovy复制stage('K8S部署') {
steps {
sh 'helm upgrade --install ruoyi ./ruoyi-chart \
--set image.tag=${BUILD_ID} \
--namespace ruoyi'
}
}
- 秘钥管理建议:
- 将kubeconfig文件保存在Jenkins凭据中
- 使用vault-plugin实现动态秘钥获取
5. 效能提升技巧
5.1 构建缓存优化
在Jenkinsfile开头添加:
groovy复制environment {
MAVEN_OPTS = '-Dmaven.repo.local=/tmp/m2repo'
}
配合Dockerfile中的缓存层:
dockerfile复制COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package
5.2 通知机制增强
除了常规的邮件通知,可以接入企业微信机器人:
groovy复制post {
failure {
sh """
curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"content": "🚨 构建失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}\n
> 原因: ${currentBuild.currentResult}\n
> 详情: ${env.BUILD_URL}"
}
}'
"""
}
}
5.3 制品库的妙用
通过Nexus管理Docker镜像:
groovy复制script {
docker.withRegistry('https://nexus.your-company.com', 'nexus-cred') {
docker.image("ruoyi-admin:${env.BUILD_ID}").push()
}
}
在实施这套流程的过程中,最大的体会是:CICD的难点不在于工具使用,而在于对项目架构和构建生命周期的深度理解。比如Ruo-Yi的quartz模块需要特殊处理数据库连接池配置,否则在k8s中会出现连接泄漏。这些细节往往需要结合具体项目反复调试才能掌握。
