# 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 部署测试环境效果如下:

