# Jenkins Maven 实践

# 1. Java 项⽬基本概述

# 1.1 什么是 Java 项⽬

简单来说就是使⽤ java 编写的代码,我们将其称为 java 项⽬。

# 1.2 Java 项⽬如何编译

由于 java 编写的代码是⽆法直接在服务器上运⾏,需要使⽤ maven ⼯具进⾏编译打包。

简单理解: Java 源代码就像汽⻋的⼀堆散件,必须组装才是⼀辆完整的汽⻋。

这⾥的 "组装汽⻋的过程" 就可以理解是 "Maven 编译打包" 的过程。

# 1.3 Java 项⽬实现架构图

# 2. Java 项⽬环境搭建

# 2.1 Haproxy 负载均衡

1、配置⽣产环境负载均衡(直接新增如下内容即可)

[root@proxy01 ~]# cat /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats level admin
    #nbproc 4
    nbthread 8
    cpu-map 1 0
    cpu-map 2 1
    cpu-map 3 2
    cpu-map 4 3
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
##listen
listen stats
  mode http
  bind 0.0.0.0:9999
  stats enable
  log global
  stats uri /haproxy-status
  stats auth xuyong:123456
  stats admin if TRUE
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend www
    bind *:80
    mode http
    acl html_web hdr_reg(host) -i html.hmallleasing.com
    use_backend web_cluster if html_web
backend web_cluster
    balance roundrobin
    option httpchk HEAD / HTTP/1.1\r\nHost:\ html.hmallleasing.com
    server 172.16.1.7 172.16.1.7:80 check port 80 inter 3s rise 2 fall 3
    server 172.16.1.8 172.16.1.8:80 check port 80 inter 3s rise 2 fall 3
frontend war
    bind *:80
    mode http
    acl war_domain hdr_reg(host) -i war.hmallleasing.com
    use_backend java_cluster if war_domain
backend java_cluster
    balance roundrobin
    option httpchk HEAD / HTTP/1.1\r\nHost:\ war.hmallleasing.com
    server 172.16.1.7 172.16.1.7:8080 check port 8080 inter 3s rise 2 fall 3
    server 172.16.1.8 172.16.1.8:8080 check port 8080 inter 3s rise 2 fall 3
# 2.2 Tomcat 集群节点

1、安装 java 环境

OracleJdk 下载地址:https://download.oracle.com/java/17/archive/jdk-17.0.12_linux-x64_bin.tar.gz

[root@web01 ~]# wget https://download.oracle.com/java/17/archive/jdk-17.0.12_linux-x64_bin.tar.gz
[root@web01 ~]# tar xf jdk-17.0.12_linux-x64_bin.tar.gz  -C /usr/local/
[root@web01 ~]# ln -s /usr/local/jdk-17.0.12/ /usr/local/jdk
#添加环境变量
[root@web01 ~]# cat /etc/profile.d/jdk.sh
export JAVA_HOME=/usr/local/jdk
export PATH=$PATH:$JAVA_HOME/bin
export JRE_HOME=$JAVA_HOME
export CLASSPATH=$JAVA_HOME/lib/:$JRE_HOME/lib/
[root@web01 ~]# source /etc/profile
[root@web01 ~]# java -version

2、安装 Tomcat

mkdir /app
wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.49/bin/apache-tomcat-10.1.49.tar.gz
tar xf apache-tomcat-10.1.49.tar.gz -C /app
ln -s /app/apache-tomcat-10.1.49 /app/tomcat
/app/tomcat/bin/startup.sh
# 2.3 验证集群环境

1、访问 http://war.hmallleasing.com:8080 / 生产环境

# 3. 手动实现 War 包项目部署

# 3.1 模拟开发提交代码
  • 1、在 gitlab 创建项目仓库 springboot-devops-war;
  • 2、下载 springboot-devops-demo-war-java17.tar.gz 代码包;
  • 3、本地推送代码至 gitlab 项目仓库;
  • 4、检查 gitlab 仓库是否有已提交的代码;
# 3.2 模拟运维拉取代码
[root@jenkins ~]# git clone git@gitlab.hmallleasing.com:root/springboot-devops-demo-war.git
# 3.3 模拟运维编译代码

1、安装 maven

[root@jenkins ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.tar.gz
[root@jenkins ~]# tar xf apache-maven-3.9.11-bin.tar.gz -C /usr/local/
[root@jenkins ~]# ln -s /usr/local/apache-maven-3.9.11 /usr/local/maven
[root@jenkins ~]# cat /etc/profile.d/maven.sh
export MAVEN_HOME=/usr/local/maven
export PATH=$MAVEN_HOME/bin:$PATH
[root@jenkins ~]# source /etc/profile.d/maven.sh 
[root@jenkins ~]# mvn -v

2、配置 maven 加速仓库,加速 jar 包下载

[root@jenkins ~]# vim /usr/local/maven/conf/settings.xml
<mirrors>
     <mirror>
         <id>alimaven</id>
         <name>aliyun maven</name>
         <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
         <mirrorOf>central</mirrorOf>
     </mirror>
</mirrors>

3、使用 maven 进行项目编译

[root@jenkins ~]# cd springboot-devops-demo-war/
[root@jenkins springboot-devops-demo-war]# mvn package -Dmaven.test.skip=true
# 3.4 模拟运维部署代码

1、对编译后的 war 包重命名为 ROOT_$(date +% F-% H-% M).war,然后推送到目标集群服务器节点;

2、删除 Tomcat 的默认 ROOT 目录;

3、创建 ROOT_$(date +% F-% H-% M) 目录,然后将 war 解压到对应的目录中;

4、创建软软链接,然后重启 Tomcat;

War_Date=$(date +%F-%H-%M)
for i in {7..8};do scp target/*.war root@172.16.1.$i:/opt/ROOT_${War_Date}.war; done
for i in {7..8};do ssh root@172.16.1.$i "rm -rf /app/tomcat/webapps/ROOT";done
for i in {7..8};do ssh root@172.16.1.$i "mkdir /opt/ROOT_${War_Date} && unzip /opt/ROOT_${War_Date}.war -d /opt/ROOT_${War_Date}"; done
for i in {7..8};do ssh root@172.16.1.$i "ln -s /opt/ROOT_${War_Date} /app/tomcat/webapps/ROOT"; done
for i in {7..8};do ssh root@172.16.1.$i "/app/tomcat/bin/shutdown.sh && /app/tomcat/bin/startup.sh"; done

5、部署成功效果图

# 4. ⾃动实现 War 包项⽬的 CI

# 4.1 安装 Maven 插件

1、安装 Maven Integration 插件,这样才能使⽤ Jenkins 构建⼀个 Maven 的项⽬。

2、告诉 Jenkins,Maven 的安装路径:点击系统 --> 全局⼯具配置 --> 新增 Maven,然后填写 Maven 路径;

[root@jenkins ~]# mvn -version
Apache Maven 3.9.11 (3e54c93a704957b63ee3494413a2b544fd3d825b)
Maven home: /usr/local/maven
Java version: 17.0.17, vendor: Oracle Corporation, runtime: /usr/local/jdk-17.0.17
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-957.el7.x86_64", arch: "amd64", family: "unix"

3、告诉 Jenkins,java 的安装路径:点击系统 --> 全局⼯具配置 --> 新增 jdk,然后填写 java 路径;

# 4.2 Jenkins 创建 Maven 项⽬

1、创建⼀个 maven 项⽬ springboot_devops_war-Shell-CI

2、基础配置:参数化构建(定义 lbservers、webservers、git_commit_id 三个变量),在 Shell 脚本中,使⽤到了 webservers、lbservers 、git_commit_id 三个变量,需要通过 jenkins 选项参数,进⾏动态传参;

lbservers 变量

webservers 变量

git_commit_id 变量

3、配置源码:填写 java 项⽬地址

4、配置 Build:在 Goals and options ,填写 package -Dmaven.test.skip=true 打包命令即可;

5、 Post Steps 添加 shell 脚本,后期发布使⽤该脚本;

# 4.3 具体脚本代码
  • 1、进⼊⼯程⽬录中,将 war 包拷⻉到被控端,并进⾏重命名为 ROOT.war ;
  • 2、调⽤ Haproxy 下线对应的节点,并且关闭对应的 Tomcat 服务;
  • 3、继续为对应的节点创建站点⽬录,并将 war 解压到站点⽬录下;
  • 4、然后继续,删除软连接,重新创建软连接;
  • 5、最后启动节点的 Tomcat 服务,并且将其加⼊到 Haproxy 集群中;
[root@jenkins ~]# cat /scripts/shell_deploy_war.sh 
#!/usr/bin/bash
#1. 变量
app_dir=/opt
app_date=$(date +%Y_%m_%d_%H_%M)
app_name=ROOT
tomcat_dir=/app/tomcat
git_commit_id=$(echo ${git_commit_id} | cut -c 1-8)
#2.haproxy 的函数
lb_server_disable(){
for i in ${lbservers}
do
    ssh root@${i} "echo 'disable server java_cluster/$1' | socat stdio /var/lib/haproxy/stats"
done
}
lb_server_enable(){
for i in ${lbservers}
do
    ssh root@${i} "echo 'enable server java_cluster/$1' | socat stdio /var/lib/haproxy/stats"
done
}
#3. 拷贝对应的 war 包到被控端
for host in ${webservers}
do
    cd ${WORKSPACE} && \
    scp target/*.war root@${host}:${app_dir}/${app_name}_${app_date}_${git_commit_id}.war
done
#4. 摘除节点并停?Tomcat 服务
for host in ${webservers}
do
    # 从负载均衡中将该节点摘除
    lb_server_disable ${host}
    ssh root@${host} "${tomcat_dir}/bin/shutdown.sh && \
    mkdir -p ${app_dir}/${app_name}_${app_date}_${git_commit_id} && \
    unzip ${app_dir}/${app_name}_${app_date}_${git_commit_id}.war -d ${app_dir}/${app_name}_${app_date}_${git_commit_id} && \
    rm -f ${app_dir}/${app_name}_${app_date}_${git_commit_id}.war && \
    rm -f ${tomcat_dir}/webapps/ROOT && \
    ln -s ${app_dir}/${app_name}_${app_date}_${git_commit_id} ${tomcat_dir}/webapps/ROOT && \
    ${tomcat_dir}/bin/startup.sh"
    # 等待 tomcat "完全就绪" 在加入集群资源池
    sleep 5
 
    # 将节点加入负载均衡资源池
    lb_server_enable ${host}
    # 为了查看滚动更新的效果(如果不需要可去除)
    sleep 5
done
# 4.4 使⽤ Jenkins 部署及测试

1、点击构建,选择需要交付的环境

2、检查部署结果

[root@web01 ~]# ll /app/tomcat/webapps
drwxr-x--- 16 root root 4096 Nov 21 00:50 docs
drwxr-x---  7 root root   99 Nov 21 00:50 examples
drwxr-x---  6 root root   79 Nov 21 00:50 host-manager
drwxr-x---  6 root root  114 Nov 21 00:50 manager
lrwxrwxrwx  1 root root   35 Nov 21 15:27 ROOT -> /opt/ROOT_2025_11_21_15_27_4e35f8e0
[root@web02 ~]# ll /app/tomcat/webapps
drwxr-x--- 16 root root 4096 Nov 21 00:34 docs
drwxr-x---  7 root root   99 Nov 21 00:34 examples
drwxr-x---  6 root root   79 Nov 21 00:34 host-manager
drwxr-x---  6 root root  114 Nov 21 00:34 manager
lrwxrwxrwx  1 root root   35 Nov 21 15:27 ROOT -> /opt/ROOT_2025_11_21_15_27_4e35f8e0

# 5. 编写 Ansible 发布脚本

# 5.1 Ansible 实现思路

1、创建 springboot_devops_war-Ansible-CI 的项⽬,基于 springboot_devops_war-Shell-CI 克隆⽽来;

2、修改 Post Steps ,移除 Shell 脚本部署⽅式,添加 Ansible 脚本部署⽅式,然后配置 Ansible 主机清单为变量名称 deploy_env_file ,后期通过 Jenkins 前端传递测试⽣产等环境⽂件;

3、配置参数化构建 deploy_env_file 变量对应的选项;

4、Ansible 前端展示效果

# 5.2 Ansible 部署脚本
[root@jenkins ~]# cat /scripts/deploy_java.yml 
- hosts: webservers
  vars:
    - work_dir: /opt
    - web_name: ROOT
    - tomcat_site: /app/tomcat/webapps
    - tomcat_dir: /app/tomcat
    - web_backend: java_cluster
    - service_port: 8080
  serial: 1 #控制每次仅操作一个主机
  tasks:
    #1. 获取一个时间,年 - 月 - 日 - 时 - 分 
    - name: Get System Time
      shell:
        cmd: "echo $(date +%F_%H_%M)"
      register: date
      delegate_to: 127.0.0.1
          
    #2. 获取项目的 war 包名称 
    - name: Get WorkSpace Work Path
      shell:
        cmd: "echo ${WORKSPACE}/target/*.war"
      register: workspace
      delegate_to: 127.0.0.1
          
    #3. 下线节点(委派给 lbservers)
    - name: offline Haproxy ""
      haproxy:
        state: disabled
        host: ''
        backend: ""
        socket: /var/lib/haproxy/stats
      delegate_to: ""
      loop: ""
          
    #4. 关闭 Tomcat Server
    - name: Systemd Tomcat Stoppend
      shell:
        cmd: "nohup /bin/shutdown.sh &"
                
    #5. 检测端口是否存活
    - name: Check Tomcat Port
      wait_for:
        port: ""
        state: stopped
                
    #6. 为 web 集群创建站点目录 /opt/ROOT-2021-10-21-10-13
    - name: Create Web Site Directory
      file:
        path: "/_"
        state: directory
                
    #7. 解压目录
    - name: Unarchive Web Code
      unarchive:
        src: ""
        dest: "/_"
          
    #8. 删除软连接
    - name: Unlink Path
      file:
        path: "/"
        state: absent
                
    #9. 重新创建连接
    - name: Create Links Path
      file:
        src: "/_"
        dest: "/"
        state: link
                
    #10. 启动 Tomcat Server
    - name: Systemd Tomcat Started
      shell:
        cmd: "nohup /bin/startup.sh &"
                
    #11. 检测端口是否存活
    - name: Check Tomcat Port
      wait_for:
        port: ""
        state: started
                
    #12. 上线节点(委派给 lbservers)
    - name: online Haproxy ""
      haproxy:
        state: enabled
        host: ''
        backend: ""
        socket: /var/lib/haproxy/stats
      delegate_to: ""
      loop: ""
# 5.3 使⽤ Jenkins 部署及验证

1、Ansible 部署测试环境效果如下:

此文章已被阅读次数:正在加载...更新于

请我喝[茶]~( ̄▽ ̄)~*

Xu Yong 微信支付

微信支付

Xu Yong 支付宝

支付宝