Jenkins实现java项目CI/CD部署

文章目录

  • 一、Java项目基本概述
    • 1.1 什么是Java项目
    • 1.2 Java项目如何编译
    • 1.3 Java项目实现架构图
    • 1.4 环境 负载均衡haproxy ,后端web集群 tomcat+java
  • 二、手动实现War包项目的CI
    • 2.1 模拟开发提交代码
    • 2.2 模拟运维拉取代码
    • 2.3模拟运维编译代码
    • 2.4 模拟运维部署代码
  • 三、Jenkins自动实现war包项目CI
    • 3.1 配置Jenkins集成Maven
    • 3.2 Jenkins创建Maven项目
    • 3.3 编写Shell发布脚本
    • 3.4 Ansible剧本发布war包
  • 四、Jenkins集成Nexus制品库
    • 4.1 Nexus作用
    • 4.2 Nexus安装
    • 4.3 Nexus配置
    • 4.4 nexus启动
    • 4.5 nexus访问
    • 4.6 配置NexusWeb
    • 4.7 配置Maven连接Nexus
    • 4.8 手动上传war包到nexus-releases
    • 4.9 自动上传war包或jar包至Nexus
    • 4.10 测试手动下载
  • 五、Jenkins基于Nexus实现War包的CI
    • 5.1 War包CI实现(Maven类型)
    • 5.2 配置Webhook触发器自动拉取代码
  • 六、Jenkins基于Nexus实现War包的CD(Freestyle风格,不需要编译)
    • 6.1 基本配置
    • 6.2 编写shell脚本
    • 6.3 编写Ansible
    • 6.4 完整测试CI与CD流程
  • 七、Jenkins实现Jar包的CI与CD
    • 7.1 Jar包CI实现(Maven类型)
    • 7.2 创建项目并加入webhook
    • 7.3 Jar包CD基于shell实现(Freestyle类型)
    • 7.3 Jar包CD基于Ansible实现(Freestyle类型)
    • 7.4 前端提交代码,自动实现CI与CD ,并且部署到测试环境

一、Java项目基本概述

1.1 什么是Java项目

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

1.2 Java项目如何编译

由于java编写的代码是无法直接在服务器上运行,需要使用maven工具进行打包。
简单理解: Java源代码就像汽车的一堆散件,必须组装才是一辆完整的汽车。
这里的 “组装汽车的过程” 就可以理解是 “Maven编译打包” 的过程。

1.3 Java项目实现架构图

Jenkins实现java项目CI/CD部署_第1张图片

1.4 环境 负载均衡haproxy ,后端web集群 tomcat+java

二、手动实现War包项目的CI

先模拟开发提交java源码–>推送至gitlab–>运维使用mvn手动编译–>最后推送war至web集群

2.1 模拟开发提交代码

1.首先在gitlab创建项目仓库
2.开发本地推送项目至gitlab项目仓库
3.检查gitlab仓库是否有已提交的代码
Jenkins实现java项目CI/CD部署_第2张图片

2.2 模拟运维拉取代码

[root@jenkins test]# git clone git@gitlab.bertwu.com:dev/spring-hello-world-war.git

2.3模拟运维编译代码

1.安装maven

[root@jenkins ~]# yum install java maven -y

2.maven编译时会下载jar包,默认走国外,比较慢,配置为阿里源。

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

3.编译

[root@jenkins ~]# mvn clean # 清除缓存

[root@jenkins spring-hello-world-war]# mvn package -Dmaven.test.skip=true # 跳过测试用例

2.4 模拟运维部署代码

1.推送war包到web的/opt目录,打上时间标签
[root@jenkins spring-hello-world-war]# for i in {7..8};do scp target/*.war [email protected].$i:/opt/ROOT_$(date +%F).war;done
2.删除原有的ROOT目录
[root@jenkins spring-hello-world-war]# for i in {7..8};do  ssh [email protected].$i "rm -rf /soft/tomcat/webapps/ROOT";done
3.创建对应目录解压war包,war包解压后为分散的文件
[root@jenkins spring-hello-world-war]# for i in {7..8};do  ssh [email protected].$i "mkdir /opt/ROOT_$(date +%F) && unzip /opt/ROOT_$(date +%F).war -d /opt/ROOT_$(date +%F)";done

在这里插入图片描述

4.建立软连接,将目录连接到/soft/tomcat/webapps/ROOT下为tomcat站点的默认目录
[root@jenkins spring-hello-world-war]# for i in {7..8};do  ssh root@172.16.1.$i "ln -s /opt/ROOT_$(date +%F) /soft/tomcat/webapps/ROOT";done

5.重启tomcat
[root@jenkins spring-hello-world-war]# for i in {7..8};do  ssh root@172.16.1.$i "pkill java && /soft/tomcat/bin/startup.sh";done

三、Jenkins自动实现war包项目CI

3.1 配置Jenkins集成Maven

1.安装 Maven Integration 插件,这样才能使用Jenkins构建一个Maven的项目。
2.告诉Jenkins,JDK的安装路径:点击系统–>全局工具配置–>新增JDK,然后填写JDK路径;
Jenkins实现java项目CI/CD部署_第3张图片

3.告诉Jenkins,Maven的安装路径:点击系统–>全局工具配置–>新增Maven,然后填写Maven路径;
Jenkins实现java项目CI/CD部署_第4张图片
具体路径查看方法:

[root@jenkins target]# mvn --version
Apache Maven 3.0.5 (Red Hat 3.0.5-17)
Maven home: /usr/share/maven
Java version: 1.8.0_302, vendor: Red Hat, Inc.
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el7_9.x86_64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.el7.x86_64", arch: "amd64", family: "unix"

3.2 Jenkins创建Maven项目

1.创建一个maven项目
2.基础配置:git参数化构建
3.配置源码:填写java项目地址ssbi
4.配置Build:在Goals and options,填写package打包命令即可;

3.3 编写Shell发布脚本

1.通过Haproxy来关闭web节点;
2.停止web节点上的Tomcat服务;
3.进入工程目录中,将war包拷贝到被控端,并进行重新命名;
4.为被控端创建目录,解压到指定的目录下;
5.删除软连接,重新创建软连接
6.启动web节点上的Tomcat服务;
7.通过Haproxy加入到集群中;

[root@jenkins scripts]# cat deploy_java.sh 
#!/usr/bin/bash
Date=$(date +%F_%H_%M)
web_dir=/opt
tomcat_path=/soft/tomcat

#上锁
if [ -f /tmp/lock ];then
	echo "脚本正在执行,请不要重复执行"
	exit
fi

# 枷锁
touch /tmp/lock 

# 下线节点
lbservers_disable (){
	for lb_host in $lbservers
	do
		ssh root@$lb_host "echo 'disable server web_cluster/$1' | socat stdio /var/lib/haproxy/stats"
	done
}

# 上线节点
lbservers_enable (){
	for lb_host in $lbservers
	do
		ssh root@$lbservers "echo 'enable server web_cluster/$1' | socat stdio /var/lib/haproxy/stats"
	done
}


for host in $webservers
do
  #下线节点
	lbservers_disable $host
	#2.将war包推送到目标集群
	echo $WORKSPACE
	cd $WORKSPACE && scp target/*.war root@$host:$web_dir/ROOT_$Date.war
  # 停止tomcat
	 ssh root@$host "pkill java"
	# 删除原有ROOT目录
	 ssh root@$host "rm -rf $tomcat_path/webapps/ROOT"
	# 创建带时间戳的ROOT目录用于解压war包
		ssh root@$host "mkdir $web_dir/ROOT_$Date"
	# 将war包解压到新创建的目录
		ssh root@$host "unzip $web_dir/ROOT_$Date.war -d $web_dir/ROOT_$Date"
	# 创建软连接
		ssh root@$host "ln -s $web_dir/ROOT_$Date $tomcat_path/webapps/ROOT"
	# 重启tomcat
		ssh root@$host "$tomcat_path/bin/startup.sh"	
	# 上线节点
	lbservers_enable $host	
	
	sleep 5

done

#解锁
rm -rf /tmp/lock

传参方式如下:
Jenkins实现java项目CI/CD部署_第5张图片

3.4 Ansible剧本发布war包

[root@jenkins scripts]# cat deploy_java_commitid.yml 
- hosts: "{{ deploy_webcluster }}"
  serial: 1
  vars:
    - web_dir: /opt
    - web_name: ROOT
    - backend_name: web_cluster
    - service_port: 8080
    - tomcat_path: /soft/tomcat

  tasks:
    - name: set system time variable
      shell:
        cmd: "date +%F:%H:%M"
      register: system_date
      delegate_to: "127.0.0.1"
    
    # 获取编译好的war绝对路径
    - name: set jenkins workspace 
      shell:
        cmd: "echo ${WORKSPACE}/target/*.war"
      register: workspace
      delegate_to: "127.0.0.1"
  
    # 获取commitid
    - name: get commit id
      shell:
        cmd: "echo ${git_commit_id} | cut -c 1-8" # 获取前8register: commit_id
      delegate_to: "127.0.0.1"


    # 下线节点
    - name: stop haproxy webcluster pool node
      haproxy:
        socket: /var/lib/haproxy/stats
        backend: "backend_name"
        state: disabled
        host: "{{ inventory_hostname }}"
      delegate_to: "{{ item }}"
      loop: "{{ groups['lbservers']}}"
  
   # 停止tomcat
    - name: stop tomcat server
      shell:
        cmd: "nohup /soft/tomcat/bin/shutdown.sh &"
        
        
  
   # 检测tomcat是否已经关闭
    - name: check tomcat port state
      wait_for:
        port: "{{ service_port }}"
        state: stopped
   

   # 创建站点目录
    - name: create web sit directory
      file:
        path: "{{ web_dir}}/{{ web_name }}_{{ system_date.stdout }}_{{ commit_id.stdout }}"
        state: directory 
  


   # 解压代码到远程
    - name: unarchive code to remote
      unarchive:
        src: "{{ workspace.stdout }}"
        dest: "{{ web_dir }}/{{ web_name }}_{{ system_date.stdout }}_{{ commit_id.stdout }}"

   # 删除旧的ROOT目录
    - name: delete old webserver link
      file:
        path: "{{ tomcat_path }}/webapps/ROOT"
        state: absent

   # 创建新的软连接
    - name: create new webserver link
      file: 
        src: "{{ web_dir}}/{{ web_name }}_{{ system_date.stdout }}_{{ commit_id.stdout }}"
        dest: "{{ tomcat_path }}/webapps/ROOT"
        state: link
 
  # 启动tomcat服务
    - name: start tomcat server
      shell:
        cmd: "nohup {{ tomcat_path }}/bin/startup.sh &"

   # 检测tomcat是否已经启动,端口是否存活
    - name: check tomcat  port state
      wait_for:
        port: "{{ service_port }}"
        state: started



   # 上线节点
    - name: start haproxy webcluster pool node
      haproxy:
        socket: /var/lib/haproxy/stats
        backend: "backend_name"
        state: enabled
        host: "{{ inventory_hostname }}"
      delegate_to: "{{ item }}" # 委派给负载均衡节点
      loop: "{{ groups['lbservers']}}"

前端参数展示:
Jenkins实现java项目CI/CD部署_第6张图片

四、Jenkins集成Nexus制品库

4.1 Nexus作用

1.加速war包编译,先从制品库中获取编译所依赖的jar包,如果制品库没有,再去阿里云上查找,同时缓存一份在制品库,下次需要时候依然走制品库(相当于中转站)
2.开发可以手动或自动提交自定义的jar包(通过http协议下载)

4.2 Nexus安装

依赖java 和maven

[root@nexus ~]# yum install java maven -y
[root@jenkins ~]# wget nexus-3.19.1-01-unix.tar.gz # 默认很慢
[root@jenkins ~]# tar xf nexus-3.19.1-01-unix.tar.gz -C /usr/local/
[root@jenkins ~]# ln -s /usr/local/nexus-3.19.1-01/ /usr/local/nexus

4.3 Nexus配置

[root@jenkins ~]# vim /usr/local/nexus/bin/nexus.rc
run_as_user="root" # nexus进程运行用户
[root@jenkins ~]# vim /usr/local/nexus/etc/nexusdefault.properties
application-port=8081 # nexus监听端口
application-host=0.0.0.0 # nexus监听地址
[root@nexus local]# vim /usr/local/nexus/bin/nexus.vmoptions # 调整启动内存,适当调整小一点
-Xms512m 
-Xmx512m

4.4 nexus启动

[root@nexus local]# /usr/local/nexus/bin/nexus start

4.5 nexus访问

默认用户名admin密码放在下述文件中,登录进去后先修改密码

# 获取默认nexus密码,用户名默认admin
[root@nexus local]# cat /usr/local/sonatype-work/nexus3/admin.password 
ef4058e5-6c4e-4b05-834c-0ebdaf7487d6

4.6 配置NexusWeb

配置nexus的中央仓库(加速jar包的下载及缓存jar包)
1.点击 settings–> Repositories --> maven-central
2.修改 proxy–> Remote storage 为http://maven.aliyun.com/nexus/content/groups/public
3.点击 save 保存
Jenkins实现java项目CI/CD部署_第7张图片

4.7 配置Maven连接Nexus

在jenkis主机上修改配置

[root@jenkins ~]# vim/etc/maven/settings.xml
# 配置nexus认证
  <servers>
    <server>
      <id>nexus-snapshotsid>
      <username>adminusername>
      <password>adminpassword>
    server>
    <server>
      <id>nexus-releasesid>
      <username>adminusername>
      <password>adminpassword>
    server>
    <server>
      <id>maven-centralid>
      <username>adminusername>
      <password>adminpassword>
    server>
  servers>


# 配置nexus仓库
<mirrors>
        <mirror>
          <id>maven-centralid>  
          <mirrorOf>*mirrorOf>
          <url>http://nexus.bertwu.net:8081/repository/maven-central/url>                                             
        mirror>

        <mirror>
          <id>nexus-snapshotsid>
          <mirrorOf>*mirrorOf>
          <url>http://nexus.bertwu.net:8081/repository/maven-snapshots/url>
        mirror>

        <mirror>
          <id>nexus-releasesid>
          <mirrorOf>*mirrorOf>
          <url>http://nexus.bertwu.net:8081/repository/maven-releases/url>
        mirror>
  mirrors>

maven-central 主要用作缓存,nexus-releases主要用于上传自己的jar包或war包

4.8 手动上传war包到nexus-releases

Jenkins实现java项目CI/CD部署_第8张图片

查看手动上传是否成功
Jenkins实现java项目CI/CD部署_第9张图片

4.9 自动上传war包或jar包至Nexus

项目下执行如下命令

mvn deploy:deploy-file \
-DgroupId=com.efsavage \
-DartifactId=hello-world-war \
-Dversion=1.0.0 \
-Dpackaging=war \
-Dfile=target/hello-world-war-1.0.0.war \
-Durl=http://nexus.bertwu.net:8081/repository/maven-releases/ \
-DrepositoryId=nexus-releases \
-DgeneratePom=true
[root@jenkins hello-world-war]# mvn deploy:deploy-file \
> -DgroupId=com.efsavage \
> -DartifactId=hello-world-war \
> -Dversion=1.0.0 \
> -Dpackaging=war \
> -Dfile=${WORKSPACE}/target/hello-world-war-1.0.0.war \
> -Durl=http://nexus.bertwu.net:8081/repository/maven-releases/ \
> -DrepositoryId=nexus-releases \
> -DgeneratePom=true

4.10 测试手动下载

wget --http-user=admin --http-passwd=admin \
http://nexus.bertwu.net:8081/repository/maven-releases/com/efsavage/hello-world-war/1.0.0/hello-world-war-1.0.0.war

五、Jenkins基于Nexus实现War包的CI

5.1 War包CI实现(Maven类型)

1.拉取代码
2.编译代码
3.编写脚本将jar包推送至nexus服务器
4.配置webhook自动触发器

编译完成后,增加一个执行Shell脚本功能,自动上传war包到制品库

[root@jenkins scripts]# cat push_nexus.sh 
# 通过pom获取信息
groupId=$(mvn help:evaluate -Dexpression=project.groupId | egrep -v "[INFO]")
artifactId=$(mvn help:evaluate -Dexpression=project.artifactId | egrep -v "[INFO]")
version=$(mvn help:evaluate -Dexpression=project.version | egrep -v "\[INFO\]")
packaging=$(mvn help:evaluate -Dexpression=project.packaging | egrep -v "[INFO]")
# 上传至nexus
mvn deploy:deploy-file \
-DgroupId=${groupId} \
-DartifactId=${artifactId} \
-Dversion=${version} \
-Dpackaging=${packaging} \
-Dfile=target/${artifactId}-${version}.${packaging} \
-Durl=http://nexus.bertwu.net:8081/repository/maven-releases/ \
-DrepositoryId=nexus-releases \
-DgeneratePom=true

Jenkins实现java项目CI/CD部署_第10张图片

允许重复上传
Jenkins实现java项目CI/CD部署_第11张图片

5.2 配置Webhook触发器自动拉取代码

Jenkins实现java项目CI/CD部署_第12张图片

Jenkins实现java项目CI/CD部署_第13张图片
在gitlab上点击设置-----集成
Jenkins实现java项目CI/CD部署_第14张图片

六、Jenkins基于Nexus实现War包的CD(Freestyle风格,不需要编译)

6.1 基本配置

1.新建任务 Spring-Hello-Shell-CD
2.配置参数化构建
Jenkins实现java项目CI/CD部署_第15张图片

Jenkins实现java项目CI/CD部署_第16张图片
前端展示效果:
Jenkins实现java项目CI/CD部署_第17张图片
这样就可以部署不同版本的war包了。

6.2 编写shell脚本

[root@jenkins scripts]# cat deploy_nexus_war.sh 
#!/usr/bin/bash
web_dir=/opt
tomcat_path=/soft/tomcat
Date=$(date +%F:%H:%M)
username=admin
password=admin
#上锁
if [ -f /tmp/lock ];then
	echo "脚本正在执行,请不要重复执行"
	exit
fi

# 枷锁
touch /tmp/lock 

# 下线节点
lbservers_disable (){
	for lb_host in $lbservers
	do
		ssh root@$lb_host "echo 'disable server web_cluster/$1' | socat stdio /var/lib/haproxy/stats"
	done
}

# 上线节点
lbservers_enable (){
	for lb_host in $lbservers
	do
		ssh root@$lbservers "echo 'enable server web_cluster/$1' | socat stdio /var/lib/haproxy/stats"
	done
}


# 从制品库获取对应版本的war包

cd $web_dir && wget --http-user=$username --http-password=$password ${java_deploy_package_url} &>/dev/null


for host in $webservers
do
  #下线节点
	lbservers_disable $host

	#2.将war包推送到目标集群
	 scp $web_dir/*.war root@$host:$web_dir/
  # 停止tomcat
	 ssh root@$host "pkill java"
	# 删除原有ROOT目录
	 ssh root@$host "rm -rf $tomcat_path/webapps/ROOT"
	# 创建带时间戳的ROOT目录用于解压war包
		ssh root@$host "mkdir $web_dir/ROOT_$Date"
	# 将war包解压到新创建的目录
		ssh root@$host "unzip $web_dir/*.war -d $web_dir/ROOT_$Date"
	# 创建软连接
		ssh root@$host "ln -s $web_dir/ROOT_$Date $tomcat_path/webapps/ROOT"
	# 重启tomcat
		ssh root@$host "$tomcat_path/bin/startup.sh"	
	# 上线节点
	lbservers_enable $host	
	
	sleep 5

	# 删除/opt下war包,保证每次部署只有一个新war包
	ssh root@$host "rm -rf $web_dir/*.war"
done

# 推送完毕删除/opt下的war包
rm -rf $web_dir/*.war

#解锁
rm -rf /tmp/lock

6.3 编写Ansible

# 1.通过不同的hosts清单文件,来区分部署的环境
# 2.下载war包
# 3.获取war包名称+版本+类型
# 4.将节点从集群摘除
# 5.关闭Tomcat,并等待彻底退出
# 6.创建web站点目录,将代码解压至指定的目录
# 7.删除软连接,重建软连接
# 8.启动tomcat,并等待启动就绪
# 9.将节点接入集群
[root@jenkins scripts]# cat deploy_nexus_war.yml 
- hosts: "{{ deploy_webcluster }}"
  serial: 1
  vars:
    - web_dir: /opt
    - web_name: ROOT
    - backend_name: java_cluster
    - service_port: 8080
    - tomcat_path: /soft/tomcat
    - username: admin
    - password: admin

  tasks:
    - name: output full name of war download
      shell:
        cmd: "echo ${java_deploy_package_url}"
      register: war_name
      delegate_to: "127.0.0.1"


    - name: output war pkg name
      shell:
        cmd: "echo ${java_deploy_package_url} | awk -F '/' '{print $NF}'"
      register: war_name_new
      delegate_to: "127.0.0.1"
      
    # 从制品库中下载war包
    - name: wget java war packages
      get_url:
        url: "{{ war_name.stdout }}"
        dest: "{{ web_dir }}/{{ war_name_new.stdout }}"
        username: admin
        password: admin
      delegate_to: "127.0.0.1"

    

    # 下线节点
    - name: stop haproxy webcluster pool node
      haproxy:
        socket: /var/lib/haproxy/stats
        backend: "backend_name"
        state: disabled
        host: "{{ inventory_hostname }}"
      delegate_to: "{{ item }}"
      loop: "{{ groups['lbservers']}}"
  
   # 停止tomcat
    - name: stop tomcat server
      shell:
        cmd: "nohup /soft/tomcat/bin/shutdown.sh &"
        
        
  
   # 检测tomcat是否已经关闭
    - name: check tomcat port state
      wait_for:
        port: "{{ service_port }}"
        state: stopped
   

   # 创建站点目录
    - name: create web sit directory
      file:
        path: "{{ web_dir}}/{{ war_name_new.stdout }}"
        state: directory 
  


   # 解压代码到远程
    - name: unarchive code to remote
      unarchive:
        src: "{{ web_dir }}/{{ war_name_new.stdout }}"
        dest: "{{ web_dir}}/{{ war_name_new.stdout }}"

   # 删除旧的ROOT目录
    - name: delete old webserver link
      file:
        path: "{{ tomcat_path }}/webapps/ROOT"
        state: absent

   # 创建新的软连接
    - name: create new webserver link
      file: 
        src: "{{ web_dir}}/{{ war_name_new.stdout }}"
        dest: "{{ tomcat_path }}/webapps/ROOT"
        state: link
 
  # 启动tomcat服务
    - name: start tomcat server
      shell:
        cmd: "nohup {{ tomcat_path }}/bin/startup.sh &"

   # 检测tomcat是否已经启动,端口是否存活
    - name: check tomcat  port state
      wait_for:
        port: "{{ service_port }}"
        state: started



   # 上线节点
    - name: start haproxy webcluster pool node
      haproxy:
        socket: /var/lib/haproxy/stats
        backend: "backend_name"
        state: enabled
        host: "{{ inventory_hostname }}"
      delegate_to: "{{ item }}" # 委派给负载均衡节点
      loop: "{{ groups['lbservers']}}"

前端展示:
Jenkins实现java项目CI/CD部署_第18张图片
Jenkins实现java项目CI/CD部署_第19张图片

6.4 完整测试CI与CD流程

1.开发更新代码,并更新pom.xml版本
2.执行Spring-Hello-CI 任务 (jenkins 读取 pom文件中的新 上传至Nexus,建议webhook自动化)
3.执行Spring-Hello-Ansible-CD 任务(Jenkins 获取 nexus 最新代码包,然后通过Shell或Ansile 推送到各个节点)
4.访问测试

七、Jenkins实现Jar包的CI与CD

7.1 Jar包CI实现(Maven类型)

# 手动编译是否正常
[root@jenkins springboot-helloworld]# mvn package

# 手动上传jar包到 nexus
[root@jenkins springboot-helloworld]# sh push_jar.sh 

[root@jenkins springboot-helloworld]# cat push_jar.sh 
#!/usr/bin/bash
groupId=$(mvn help:evaluate -Dexpression=project.groupId | egrep -v "[INFO]")
artifactId=$(mvn help:evaluate -Dexpression=project.artifactId | egrep -v "[INFO]")
version=$(mvn help:evaluate -Dexpression=project.version | egrep -v "\[INFO\]")
packaging=$(mvn  help:evaluate -Dexpression=project.packaging | egrep -v "[INFO]")

# 上传至nexus
mvn deploy:deploy-file \
-DgroupId=${groupId} \
-DartifactId=${artifactId} \
-Dversion=${version} \
-Dpackaging=${packaging} \
-Dfile=${WORKSPACE}/target/${artifactId}-${version}.${packaging} \
-Durl=http://nexus.bertwu.net:8081/repository/maven-releases/ \
-DrepositoryId=nexus-releases \
-DgeneratePom=true


# 测试手动下载
[root@jenkins springboot-helloworld]# wget -O  --http-user=admin --http-password=admin http://nexus.bertwu.net:8081/repository/maven-releases/demo/demo-service/1.0/demo-service-1.0.jar

7.2 创建项目并加入webhook

1.jekins创建项目 Spring-Hello-Naxus-Jar-CI
2.gitlab上创建项目 sprint-hello-world-jar
3.推送项目代码到远程仓库‘
4.项目配置webhook,配置maven编译,构建时执行push_jar.sh脚本将jar包推送到nexus仓库。

7.3 Jar包CD基于shell实现(Freestyle类型)

1.新建任务Spring-Hello-Jar-Shell-CD
2.参数化构建部分参数展示,执行shell脚本,从制品库拉取对应的jar包到后端服务器启动。

Jenkins实现java项目CI/CD部署_第20张图片
Jenkins实现java项目CI/CD部署_第21张图片
3.前端参数展示:
Jenkins实现java项目CI/CD部署_第22张图片
4.shell脚本

[root@jenkins scripts]# cat deploy_nexus_jar.sh 
#!/usr/bin/bash
web_dir=/opt
username=admin
password=admin
server_port=8899

#上锁
if [ -f /tmp/lock ];then
	echo "脚本正在执行,请不要重复执行"
	exit
fi

# 枷锁
touch /tmp/lock 


# 提取包名称例如demo-service-2.0.jar
pkg_name=$(echo ${java_deploy_package_url##*/})

# 基于包名称提取 demo-service 用于启停对应的java 进程
pkg_process_name=$(echo ${pkg_name%-*})


# 下线节点
lbservers_disable (){
	for lb_host in $lbservers
	do
		ssh root@$lb_host "echo 'disable server web_cluster/$1' | socat stdio /var/lib/haproxy/stats"
	done
}

# 上线节点
lbservers_enable (){
	for lb_host in $lbservers
	do
		ssh root@$lbservers "echo 'enable server web_cluster/$1' | socat stdio /var/lib/haproxy/stats"
	done
}


# 从制品库获取对应版本的war包
cd $web_dir && wget --http-user=$username --http-password=$password ${java_deploy_package_url} &>/dev/null

# 推送jar包到各个节点
for host in $webservers
do
  #下线节点
	lbservers_disable $host

	#2.将war包推送到目标集群
	 scp $web_dir/$pkg_name  root@$host:$web_dir/
  # 停止以前对应名称的java 服务
	 ssh root@$host "jar_pid=$(ps aux | grep $pkg_process_name | awk '{print $2}') && kill $jar_pid"

	# 启动 java jar包
	ssh root@$host "nohup java -jar $web_dir/$pkg_name --server.port=$server_port &>/dev/null &"

	# 上线节点
	lbservers_enable $host	
	
	sleep 5
done


#解锁
rm -rf /tmp/lock

7.3 Jar包CD基于Ansible实现(Freestyle类型)

[root@jenkins scripts]# cat deploy_nexus_jar.yml 
- hosts: "{{ deploy_webcluster }}"
  serial: 1
  vars:
    - web_dir: /opt
    - backend_name: jar_cluster
    - service_port: 8899

  tasks:
    # 获取jar包全路径
    - name: output full name of jar download
      shell:
        cmd: "echo ${java_deploy_package_url}"
      register: jar_name
      delegate_to: "127.0.0.1"

    # 获取jia包名称例如demo-service-2.0.jar
    - name: output jar pkg name
      shell:
        cmd: "echo ${java_deploy_package_url} | awk -F '/' '{print $NF}'"
      register: jar_pkg_name
      delegate_to: "127.0.0.1"
    

    - name: print jar_pkg_name
      debug:
        msg: "{{ jar_pkg_name.stdout }}"

    # 基于包名提取demo-service用于启停java进程
    - name: get java process name
      shell:
        cmd: "name=$(echo ${java_deploy_package_url} | awk -F '/' '{print $NF}') &&  echo ${name%-*} "
      register: pkg_process_name
      delegate_to: "127.0.0.1"
      
    - name: print pkg_process_name
      debug:
        msg: "{{ pkg_process_name.stdout  }}"

    # 从制品库中下载jar包
    - name: wget java jar packages
      get_url:
        url: "{{ jar_name.stdout }}"
        dest: "{{ web_dir }}/{{ jar_pkg_name.stdout }}"
        username: admin
        password: admin
      delegate_to: "127.0.0.1"

    

    # 下线节点
    - name: stop haproxy webcluster pool node
      haproxy:
        socket: /var/lib/haproxy/stats
        backend: "backend_name"
        state: disabled
        host: "{{ inventory_hostname }}"
      delegate_to: "{{ item }}"
      loop: "{{ groups['lbservers']}}"
  
   
   # 检查对应进程是否存在
    - name: check jar process status
      shell:
        cmd: "ps aux | grep {{ pkg_process_name.stdout }} | grep -v grep | awk '{print $2}'"
      register: jar_pid
      ignore_errors: yes
   
    - name: print
      debug:
        msg: "{{ jar_pid.stdout }}" 

   # 停止java服务
    - name: stop java service
      shell:
        cmd: "kill {{ jar_pid.stdout }}"
      ignore_errors: yes

       
  
   # 检测对应的java服务是否已经关闭
    - name: check java port state
      wait_for:
        port: "{{ service_port }}"
        state: stopped
   


   # 拷贝代码到远程
    - name: cope code to remote
      copy:
        src:  "{{ web_dir }}/{{ jar_pkg_name.stdout }}"
        dest: "{{ web_dir }}/{{ jar_pkg_name.stdout }}"

 
  # 启动java服务
    - name: start java server
      shell:
        cmd: "nohup java -jar {{ web_dir }}/{{ jar_pkg_name.stdout }} --server.port={{ service_port }} &>/dev/null &"
  
   # 检测java是否已经启动,端口是否存活
    - name: check java  port state
      wait_for:
        port: "{{ service_port }}"
        state: started



   # 上线节点
    - name: start haproxy webcluster pool node
      haproxy:
        socket: /var/lib/haproxy/stats
        backend: "backend_name"
        state: enabled
        host: "{{ inventory_hostname }}"
      delegate_to: "{{ item }}" # 委派给负载均衡节点
      loop: "{{ groups['lbservers']}}"

Jenkins实现java项目CI/CD部署_第23张图片

7.4 前端提交代码,自动实现CI与CD ,并且部署到测试环境

克隆Spring-Hello-Jar-Ansible-CD项目为Spring-Hello-Jar-Ansible-CD-Auto-Test-Env
也就是Spring-Hello-Jar-Ansible-CD-Auto-Test-Env 项目的构建需要依赖于Spring-Hello-Naxus-Jar-CI项目
Jenkins实现java项目CI/CD部署_第24张图片
七层haproxy负载均衡配置

[root@proxy01 ~]# cat /etc/haproxy/conf.d/jekins_haproxy.cfg 
frontend www
	bind *:80
	mode http

	acl html_web hdr(host) -i html.bertwu.net
	use_backend web_cluster if html_web

	acl java_web hdr(host) -i war.bertwu.net
	use_backend java_cluster if java_web
	
	acl jar_web hdr(host) -i jar.bertwu.net
	use_backend jar_cluster if jar_web


	backend web_cluster
		balance roundrobin
		server 172.16.1.7 172.16.1.7:80 check port 80
		server 172.16.1.8 172.16.1.8:80 check port 80


	backend java_cluster
		balance roundrobin
		server 172.16.1.7 172.16.1.7:8080 check port 8080
		server 172.16.1.8 172.16.1.8:8080 check port 8080
		
	backend jar_cluster
		balance roundrobin
		server 172.16.1.7 172.16.1.7:8899 check port 8899
		server 172.16.1.8 172.16.1.8:8899 check port 8899
[root@proxy01 ~]# 

你可能感兴趣的:(CI/CD,jenkins,java,运维,ci/cd)