UJCMS持续集成:Jenkins自动化部署

UJCMS持续集成:Jenkins自动化部署

【免费下载链接】ujcms Java开源网站内容管理系统(java cms)。使用SpringBoot、MyBatis、Spring Security、Lucene、FreeMarker、TypeScript、Vue3、ElementPlus等技术开发。 【免费下载链接】ujcms 项目地址: https://gitcode.com/dromara/ujcms

还在为UJCMS项目的手动部署而烦恼吗?每次代码更新都需要手动编译、打包、部署,既耗时又容易出错。本文将为你详细介绍如何使用Jenkins实现UJCMS项目的自动化部署,让你彻底告别重复劳动,实现一键部署的DevOps体验。

通过本文,你将掌握:

  • Jenkins环境搭建与插件配置
  • UJCMS项目的Maven构建配置
  • 自动化部署流水线设计
  • Docker容器化部署方案
  • 邮件通知与监控告警机制

环境准备与Jenkins安装

系统要求

在开始之前,确保你的服务器满足以下要求:

组件版本要求说明
JDK11或17UJCMS运行环境
Maven3.6.3+项目构建工具
MySQL8.0+数据库服务
Docker20.10+容器化部署(可选)
Jenkins2.346+持续集成工具

Jenkins安装与配置

# 安装Jenkins(以Ubuntu为例)
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

# 启动Jenkins服务
sudo systemctl start jenkins
sudo systemctl enable jenkins

# 查看初始密码
sudo cat /var/lib/jenkins/secrets/initialAdminPassword

安装完成后,访问 http://服务器IP:8080 完成Jenkins的初始配置。

必备插件安装

在Jenkins的插件管理中安装以下关键插件:

  • Maven Integration: Maven项目支持
  • Pipeline: 流水线功能
  • Git: Git版本控制
  • SSH: 远程部署支持
  • Email Extension: 邮件通知
  • Docker: 容器化支持

UJCMS项目配置

项目结构分析

UJCMS采用标准的Maven项目结构,支持两种打包方式:

mermaid

Maven构建配置

UJCMS的pom.xml文件中已经预置了两种构建profile:

<profiles>
    <profile>
        <id>jar</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <project.packaging>jar</project.packing>
        </properties>
    </profile>
    <profile>
        <id>war</id>
        <properties>
            <project.packaging>war</project.packaging>
        </properties>
    </profile>
</profiles>

Jenkins流水线设计

基础流水线脚本

创建Jenkinsfile文件,定义自动化部署流程:

pipeline {
    agent any
    tools {
        maven 'M3'
        jdk 'JDK11'
    }
    environment {
        PROJECT_NAME = 'ujcms'
        VERSION = '9.9.0'
        DEPLOY_TYPE = 'jar' // 可选: jar 或 war
    }
    stages {
        stage('代码检出') {
            steps {
                git branch: 'main', 
                    url: 'https://gitcode.com/dromara/ujcms.git'
            }
        }
        stage('依赖检查') {
            steps {
                sh 'mvn dependency:tree'
            }
        }
        stage('单元测试') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
        stage('编译打包') {
            steps {
                sh "mvn clean package -P ${DEPLOY_TYPE} -DskipTests"
            }
        }
        stage('部署到测试环境') {
            steps {
                script {
                    if (DEPLOY_TYPE == 'jar') {
                        deployJar()
                    } else {
                        deployWar()
                    }
                }
            }
        }
        stage('自动化测试') {
            steps {
                // 执行集成测试
                echo '运行自动化测试...'
            }
        }
        stage('部署到生产环境') {
            when {
                expression { 
                    currentBuild.result == null || currentBuild.result == 'SUCCESS' 
                }
            }
            steps {
                script {
                    if (DEPLOY_TYPE == 'jar') {
                        deployJarProduction()
                    } else {
                        deployWarProduction()
                    }
                }
            }
        }
    }
    post {
        success {
            emailext (
                subject: "SUCCESS: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
                body: """项目构建成功!
项目: ${env.JOB_NAME}
构建号: ${env.BUILD_NUMBER}
构建日志: ${env.BUILD_URL}console""",
                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}console""",
                to: 'dev-team@example.com'
            )
        }
    }
}

// JAR部署方法
def deployJar() {
    sh '''
        # 停止现有服务
        pkill -f "ujcms.*jar" || true
        
        # 备份旧版本
        cp target/ujcms-*.jar /opt/ujcms/backup/ujcms-$(date +%Y%m%d%H%M%S).jar
        
        # 部署新版本
        cp target/ujcms-*.jar /opt/ujcms/
        cp -r src/main/webapp/ /opt/ujcms/static/
        cp src/main/resources/application.yaml /opt/ujcms/config/
        
        # 启动服务
        cd /opt/ujcms
        nohup java -jar ujcms-*.jar > app.log 2>&1 &
    '''
}

// WAR部署方法  
def deployWar() {
    sh '''
        # 停止Tomcat
        systemctl stop tomcat
        
        # 备份旧版本
        cp /opt/tomcat/webapps/ROOT.war /opt/ujcms/backup/ROOT-$(date +%Y%m%d%H%M%S).war
        
        # 部署新版本
        cp target/ujcms-*.war /opt/tomcat/webapps/ROOT.war
        
        # 启动Tomcat
        systemctl start tomcat
    '''
}

Docker容器化部署

UJCMS项目提供了Dockerfile,支持容器化部署:

# 构建阶段
FROM eclipse-temurin:17-jre-noble AS builder
WORKDIR /ujcms
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} ujcms.jar
RUN java -Djarmode=layertools -jar ujcms.jar extract

# 运行阶段
FROM eclipse-temurin:17-jre-noble
WORKDIR /ujcms

COPY --from=builder ujcms/dependencies/ ./
COPY --from=builder ujcms/spring-boot-loader/ ./
COPY --from=builder ujcms/snapshot-dependencies/ ./
COPY --from=builder ujcms/application/ ./

COPY --from=builder ujcms/application/BOOT-INF/classes/application-docker.yaml ./BOOT-INF/classes/config/application.yaml
COPY src/main/webapp/ /usr/src/ujcms/

VOLUME ["/ujcms/static"]
EXPOSE 8080

COPY --chmod=755 docker/docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["java", "org.springframework.boot.loader.JarLauncher"]

在Jenkins流水线中添加Docker构建阶段:

stage('Docker构建') {
    steps {
        script {
            docker.build("ujcms:${env.BUILD_NUMBER}", ".")
        }
    }
}

stage('Docker部署') {
    steps {
        script {
            docker.withRegistry('https://registry.example.com', 'docker-credentials') {
                docker.image("ujcms:${env.BUILD_NUMBER}").push()
            }
            
            // 在目标服务器执行部署
            sshagent(['deploy-key']) {
                sh """
                    ssh deploy@prod-server "
                        docker pull registry.example.com/ujcms:${env.BUILD_NUMBER}
                        docker stop ujcms-container || true
                        docker rm ujcms-container || true
                        docker run -d \
                            --name ujcms-container \
                            -p 8080:8080 \
                            -v /data/ujcms/static:/ujcms/static \
                            -v /data/ujcms/logs:/ujcms/logs \
                            registry.example.com/ujcms:${env.BUILD_NUMBER}
                    "
                """
            }
        }
    }
}

数据库自动化管理

数据库迁移策略

UJCMS使用Liquibase进行数据库版本管理,Jenkins可以集成数据库变更:

stage('数据库迁移') {
    steps {
        sh '''
            # 执行数据库变更
            mvn liquibase:update \
                -Dliquibase.url=jdbc:mysql://localhost:3306/ujcms \
                -Dliquibase.username=ujcms \
                -Dliquibase.password=password
        '''
    }
}

数据库备份与恢复

# 备份脚本
#!/bin/bash
DATE=$(date +%Y%m%d%H%M%S)
mysqldump -u ujcms -p password ujcms > /backup/ujcms_${DATE}.sql
gzip /backup/ujcms_${DATE}.sql

# 保留最近7天备份
find /backup -name "ujcms_*.sql.gz" -mtime +7 -delete

监控与告警

健康检查配置

在application.yaml中添加健康检查端点:

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: always

Jenkins监控配置

stage('健康检查') {
    steps {
        script {
            def response = httpRequest 'http://localhost:8080/actuator/health'
            if (response.status != 200) {
                error "应用健康检查失败: ${response.content}"
            }
            
            // 检查数据库连接
            def dbStatus = sh(script: '''
                mysql -u ujcms -ppassword -e "SELECT 1" ujcms > /dev/null 2>&1
                echo $?
            ''', returnStdout: true).trim()
            
            if (dbStatus != "0") {
                error "数据库连接检查失败"
            }
        }
    }
}

高级部署策略

蓝绿部署方案

mermaid

金丝雀发布

stage('金丝雀发布') {
    steps {
        script {
            // 部署到部分服务器
            def canaryServers = ['server1', 'server2']
            canaryServers.each { server ->
                sshagent(['deploy-key']) {
                    sh """
                        ssh deploy@${server} "
                            docker pull registry.example.com/ujcms:${env.BUILD_NUMBER}
                            docker stop ujcms-canary || true
                            docker rm ujcms-canary || true
                            docker run -d --name ujcms-canary \
                                -p 8080:8080 \
                                registry.example.com/ujcms:${env.BUILD_NUMBER}
                        "
                    """
                }
            }
            
            // 监控金丝雀版本
            sleep time: 300, unit: 'SECONDS'
            def metrics = getCanaryMetrics()
            
            if (metrics.errorRate < 0.01 && metrics.responseTime < 1000) {
                echo "金丝雀发布成功,开始全量部署"
                fullDeployment()
            } else {
                echo "金丝雀发布失败,执行回滚"
                rollbackCanary()
            }
        }
    }
}

最佳实践与优化建议

性能优化配置

# application.yaml 优化配置
spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

server:
  tomcat:
    max-threads: 200
    min-spare-threads: 10

安全加固措施

stage('安全扫描') {
    steps {
        // 使用OWASP Dependency-Check进行依赖漏洞扫描
        dependencyCheck arguments: '''
            --scan target/ujcms-*.jar 
            --format HTML 
            --out reports/dependency-check
        ''', odcInstallation: 'DC'
        
        // 使用SonarQube进行代码质量检查
        withSonarQubeEnv('sonar-server') {
            sh 'mvn sonar:sonar'
        }
    }
}

故障排除与常见问题

常见部署问题解决

问题现象可能原因解决方案
启动时报数据库连接错误数据库配置错误检查application.yaml中的数据库连接配置
静态资源404部署路径配置问题检查上下文路径配置
验证码无法显示字体缺失安装fontconfig组件
表结构升级失败Liquibase锁问题清理databasechangeloglock表

日志监控配置

# 日志轮转配置
/opt/ujcms/app.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
}

总结

通过本文的Jenkins自动化部署方案,你可以实现UJCMS项目的全流程自动化:

  1. 代码提交触发自动构建
  2. 自动化测试与质量检查
  3. 多环境一键部署
  4. 容器化与云原生支持
  5. 完善的监控告警机制

这种自动化部署方式不仅提高了部署效率,还大大减少了人为错误,确保了部署的一致性和可靠性。无论是小型团队还是大型企业,都能从中获得显著的DevOps效益。

建议根据实际业务需求,选择合适的部署策略(JAR/WAR/Docker),并逐步完善监控告警体系,构建真正意义上的持续交付流水线。

【免费下载链接】ujcms Java开源网站内容管理系统(java cms)。使用SpringBoot、MyBatis、Spring Security、Lucene、FreeMarker、TypeScript、Vue3、ElementPlus等技术开发。 【免费下载链接】ujcms 项目地址: https://gitcode.com/dromara/ujcms

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

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

抵扣说明:

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

余额充值