RuoYi-Cloud 持续集成部署实战指南

RuoYi-Cloud 持续集成部署实战指南

【免费下载链接】RuoYi-Cloud 🎉 基于Spring Boot、Spring Cloud & Alibaba的分布式微服务架构权限管理系统,同时提供了 Vue3 的版本 【免费下载链接】RuoYi-Cloud 项目地址: https://gitcode.com/yangzongzhuan/RuoYi-Cloud

前言:微服务架构下的部署挑战

在当今快速迭代的软件开发环境中,微服务架构已成为企业级应用的主流选择。RuoYi-Cloud作为基于Spring Cloud Alibaba的分布式微服务权限管理系统,其复杂的服务依赖关系和部署流程给传统的手动部署带来了巨大挑战。你是否曾面临以下困境:

  • 多服务编译打包耗时冗长,手动操作易出错
  • 测试环境、预发布环境、生产环境部署流程不一致
  • 版本回滚困难,故障排查效率低下
  • 团队协作中代码集成频繁冲突

本文将为你全面解析RuoYi-Cloud项目的持续集成部署方案,通过实战案例展示如何构建高效、可靠的自动化部署流水线。

技术架构深度解析

系统模块拓扑

mermaid

关键组件版本矩阵

组件版本作用端口
Spring Boot2.7.18微服务框架-
Spring Cloud2021.0.9微服务治理-
Nacos2.x服务注册发现8848
MySQL5.7关系型数据库3306
Redislatest缓存会话管理6379
Nginxlatest反向代理负载均衡80

持续集成部署流水线设计

整体架构设计

mermaid

环境策略规划

环境用途部署策略验证要求
开发环境日常开发测试自动部署基础功能验证
测试环境集成测试定时部署完整流程验证
预发布环境生产前验证手动触发生产环境模拟
生产环境线上服务蓝绿部署业务监控验证

Jenkins流水线实战配置

基础环境准备

# 安装JDK 8
sudo apt-get install openjdk-8-jdk

# 安装Maven
wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz
tar -zxvf apache-maven-3.9.9-bin.tar.gz -C /usr/local/

# 安装Docker
curl -fsSL https://get.docker.com | bash

# 安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Jenkinsfile核心配置

pipeline {
    agent any
    environment {
        // Maven配置
        MAVEN_HOME = '/usr/local/apache-maven-3.9.9'
        PATH = "${MAVEN_HOME}/bin:${PATH}"
        
        // 镜像仓库配置
        DOCKER_REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
        PROJECT_NAMESPACE = 'ruoyi-cloud'
        
        // 环境变量
        DEPLOY_ENV = 'test'
    }
    
    stages {
        stage('代码检出') {
            steps {
                git branch: 'main', 
                url: 'https://gitcode.com/yangzongzhuan/RuoYi-Cloud.git',
                credentialsId: 'git-credentials'
            }
        }
        
        stage('依赖安装') {
            steps {
                sh 'mvn clean install -DskipTests'
            }
        }
        
        stage('单元测试') {
            steps {
                sh 'mvn test -pl ruoyi-common-core,ruoyi-auth,ruoyi-gateway'
            }
            post {
                always {
                    junit '**/target/surefire-reports/*.xml'
                }
            }
        }
        
        stage('编译打包') {
            steps {
                script {
                    // 编译所有模块
                    sh 'mvn package -DskipTests -Pprod'
                    
                    // 复制前端资源
                    dir('ruoyi-ui') {
                        sh 'npm install'
                        sh 'npm run build:prod'
                    }
                }
            }
        }
        
        stage('Docker镜像构建') {
            steps {
                script {
                    // 准备部署文件
                    sh 'chmod +x docker/copy.sh'
                    sh './docker/copy.sh'
                    
                    // 构建基础服务镜像
                    sh 'docker-compose -f docker/docker-compose.yml build ruoyi-mysql ruoyi-redis ruoyi-nacos'
                    
                    // 构建业务服务镜像
                    def services = ['ruoyi-gateway', 'ruoyi-auth', 'ruoyi-modules-system', 
                                  'ruoyi-modules-gen', 'ruoyi-modules-job', 'ruoyi-modules-file']
                    services.each { service ->
                        sh "docker-compose -f docker/docker-compose.yml build ${service}"
                    }
                }
            }
        }
        
        stage('镜像推送') {
            steps {
                script {
                    // 登录镜像仓库
                    withCredentials([usernamePassword(
                        credentialsId: 'docker-registry', 
                        usernameVariable: 'DOCKER_USER', 
                        passwordVariable: 'DOCKER_PASS'
                    )]) {
                        sh "echo ${DOCKER_PASS} | docker login -u ${DOCKER_USER} --password-stdin ${DOCKER_REGISTRY}"
                    }
                    
                    // 标记并推送镜像
                    def images = [
                        'ruoyi-gateway:latest', 'ruoyi-auth:latest', 'ruoyi-modules-system:latest',
                        'ruoyi-modules-gen:latest', 'ruoyi-modules-job:latest', 'ruoyi-modules-file:latest'
                    ]
                    
                    images.each { image ->
                        def targetImage = "${DOCKER_REGISTRY}/${PROJECT_NAMESPACE}/${image}"
                        sh "docker tag ${image} ${targetImage}"
                        sh "docker push ${targetImage}"
                    }
                }
            }
        }
        
        stage('部署测试环境') {
            when {
                expression { DEPLOY_ENV == 'test' }
            }
            steps {
                script {
                    // 更新docker-compose配置
                    sh "sed -i 's/image:.*/image: ${DOCKER_REGISTRY}\\/${PROJECT_NAMESPACE}\\/&/' docker/docker-compose.yml"
                    
                    // 部署基础服务
                    sh 'docker-compose -f docker/docker-compose.yml up -d ruoyi-mysql ruoyi-redis ruoyi-nacos'
                    
                    // 等待基础服务就绪
                    sleep time: 60, unit: 'SECONDS'
                    
                    // 部署业务服务
                    sh 'docker-compose -f docker/docker-compose.yml up -d ruoyi-gateway ruoyi-auth ruoyi-modules-system'
                    
                    // 健康检查
                    sh '''
                        until curl -f http://localhost:8080/actuator/health; do
                            echo "等待服务启动..."
                            sleep 10
                        done
                    '''
                }
            }
        }
    }
    
    post {
        success {
            emailext (
                subject: "SUCCESS: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
                body: """构建成功!
                项目: ${env.JOB_NAME}
                构建编号: ${env.BUILD_NUMBER}
                构建地址: ${env.BUILD_URL}
                变更记录: ${currentBuild.changeSets}""",
                to: 'dev-team@example.com'
            )
        }
        failure {
            emailext (
                subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
                body: """构建失败!
                项目: ${env.JOB_NAME}
                构建编号: ${env.BUILD_NUMBER}
                构建地址: ${env.BUILD_URL}
                失败原因: ${currentBuild.result}""",
                to: 'dev-team@example.com'
            )
        }
    }
}

Docker优化配置策略

多阶段构建优化

# 第一阶段:构建阶段
FROM maven:3.9.9-amazoncorretto-8 as builder
WORKDIR /app
COPY . .
RUN mvn package -DskipTests -Pprod

# 第二阶段:运行阶段
FROM openjdk:8-jre-slim
WORKDIR /home/ruoyi

# 安装必要的工具
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    && rm -rf /var/lib/apt/lists/*

# 复制构建产物
COPY --from=builder /app/ruoyi-gateway/target/ruoyi-gateway.jar .
COPY --from=builder /app/docker/ruoyi/gateway/dockerfile .

# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
    CMD curl -f http://localhost:8080/actuator/health || exit 1

# 启动服务
ENTRYPOINT ["java", "-jar", "ruoyi-gateway.jar"]

资源限制配置

version: '3.8'
services:
  ruoyi-gateway:
    image: registry.cn-hangzhou.aliyuncs.com/ruoyi-cloud/ruoyi-gateway:latest
    container_name: ruoyi-gateway
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
    ports:
      - "8080:8080"
    environment:
      - JAVA_OPTS=-Xms256m -Xmx512m -XX:MaxMetaspaceSize=256m
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

数据库迁移与版本控制

Flyway数据库迁移配置

<!-- pom.xml 添加依赖 -->
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>9.22.0</version>
</dependency>

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-mysql</artifactId>
    <version>9.22.0</version>
</dependency>
# application.yml 配置
spring:
  flyway:
    enabled: true
    locations: classpath:db/migration
    baseline-on-migrate: true
    validate-on-migrate: true
    out-of-order: false

迁移脚本示例

-- V1__init_schema.sql
CREATE TABLE IF NOT EXISTS sys_user (
    user_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
    dept_id BIGINT COMMENT '部门ID',
    user_name VARCHAR(30) NOT NULL COMMENT '用户账号',
    nick_name VARCHAR(30) NOT NULL COMMENT '用户昵称',
    user_type VARCHAR(2) DEFAULT '00' COMMENT '用户类型(00系统用户)',
    email VARCHAR(50) DEFAULT '' COMMENT '用户邮箱',
    phonenumber VARCHAR(11) DEFAULT '' COMMENT '手机号码',
    sex CHAR(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
    avatar VARCHAR(100) DEFAULT '' COMMENT '头像地址',
    password VARCHAR(100) DEFAULT '' COMMENT '密码',
    status CHAR(1) DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
    del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
    login_ip VARCHAR(128) DEFAULT '' COMMENT '最后登录IP',
    login_date DATETIME COMMENT '最后登录时间',
    create_by VARCHAR(64) DEFAULT '' COMMENT '创建者',
    create_time DATETIME COMMENT '创建时间',
    update_by VARCHAR(64) DEFAULT '' COMMENT '更新者',
    update_time DATETIME COMMENT '更新时间',
    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',
    PRIMARY KEY (user_id)
) ENGINE=InnoDB AUTO_INCREMENT=100 COMMENT='用户信息表';

监控与日志收集体系

Prometheus监控配置

# application.yml 监控配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
  metrics:
    export:
      prometheus:
        enabled: true
    tags:
      application: ${spring.application.name}

ELK日志收集配置

<!-- 添加Logstash依赖 -->
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>7.4</version>
</dependency>
<!-- logback-spring.xml -->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>logstash:5044</destination>
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
        <customFields>{"application":"ruoyi-gateway","environment":"${spring.profiles.active}"}</customFields>
    </encoder>
</appender>

<root level="INFO">
    <appender-ref ref="LOGSTASH" />
    <appender-ref ref="CONSOLE" />
</root>

安全与权限控制

部署环境安全配置

# 生产环境安全配置
spring:
  security:
    user:
      name: admin
      password: ${APP_SECRET_PASSWORD}
  cloud:
    nacos:
      config:
        server-addr: nacos:8848
        namespace: production
        group: PROD_GROUP

Kubernetes Secret管理

apiVersion: v1
kind: Secret
metadata:
  name: ruoyi-cloud-secrets
type: Opaque
data:
  mysql-password: cGFzc3dvcmQ=  # base64 encoded
  redis-password: cGFzc3dvcmQ=
  jwt-secret: c2VjcmV0LWtleQ==

故障排查与恢复策略

常见问题排查指南

问题现象可能原因解决方案
服务启动失败依赖服务未就绪增加健康检查等待时间
数据库连接超时网络策略限制检查防火墙规则
内存溢出JVM参数配置不当调整-Xmx参数
镜像拉取失败镜像仓库认证问题更新docker login凭证

自动化回滚机制

stage('回滚机制') {
    steps {
        script {
            try {
                // 部署新版本
                sh 'docker-compose up -d'
                
                // 健康检查
                timeout(time: 5, unit: 'MINUTES') {
                    waitUntil {
                        sh 'curl -f http://localhost:8080/actuator/health'
                        return true
                    }
                }
            } catch (Exception e) {
                // 自动回滚到上一个版本
                echo "部署失败,执行回滚"
                sh 'docker-compose down'
                sh 'docker-compose up -d --rollback'
                
                // 发送告警通知
                emailext(
                    subject: "DEPLOYMENT ROLLBACK: ${env.JOB_NAME}",
                    body: "部署失败已自动回滚,请及时排查问题",
                    to: 'dev-ops@example.com'
                )
                error("部署失败: ${e.getMessage()}")
            }
        }
    }
}

性能优化建议

JVM调优参数

# 生产环境JVM参数
JAVA_OPTS="-server -Xms2g -Xmx2g -XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=8 \
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=4 \
-XX:ConcGCThreads=2 -XX:InitiatingHeapOccupancyPercent=70 \
-XX:+ExplicitGCInvokesConcurrent -XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/home/ruoyi/logs/heapdump.hprof"

数据库连接池优化

# Druid连接池配置
spring:
  datasource:
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      max-wait: 60000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 1
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false

总结与最佳实践

通过本文的详细讲解,我们构建了一套完整的RuoYi-Cloud持续集成部署体系。关键实践总结如下:

  1. 标准化流水线:通过Jenkins Pipeline实现构建、测试、部署的全流程自动化
  2. 容器化部署:利用Docker和Docker Compose实现环境一致性和快速部署
  3. 版本控制:采用Flyway管理数据库 schema 变更,确保数据一致性
  4. 监控告警:集成Prometheus和ELK实现全方位的监控和日志收集
  5. 安全加固:通过Secret管理和网络策略提升部署安全性

这套方案不仅适用于RuoYi-Cloud项目,也可以作为其他Spring Cloud微服务项目的持续集成部署参考模板。在实际应用中,建议根据具体业务需求和环境特点进行适当调整和优化。

持续集成部署是一个不断演进的过程,建议团队定期回顾和改进部署流程,结合业务发展和技术演进持续优化,构建更加高效、可靠的软件交付体系。

【免费下载链接】RuoYi-Cloud 🎉 基于Spring Boot、Spring Cloud & Alibaba的分布式微服务架构权限管理系统,同时提供了 Vue3 的版本 【免费下载链接】RuoYi-Cloud 项目地址: https://gitcode.com/yangzongzhuan/RuoYi-Cloud

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值