Jenkins 基于tag发布回滚
Jenkins实现Tag构建
1. 编辑脚本拉取代码的脚本
[root@jenkins /scripts]# cat html_deploy_tag.sh
#!/usr/bin/bash
Date=$(date +%F-%H-%M)
web_server="192.168.1.92 192.168.1.93"
Name=${Date}-${Tag} # 注意这里的“Tag”变量,是跟jenkins中相对应的,等一下在jenkins中要配置的变量
code_tar () {
cd /var/lib/jenkins/jobs/freestyle-monitor/workspace
tar czf /opt/web-${Name}.tar.gz ./*
}
scp_web () {
for host in $web_server
do
scp -r /opt/web-${Name}.tar.gz root@${host}:/code/
ssh root@${host} "mkdir -p /code/web-${Name} && \
tar xf /code/web-${Name}.tar.gz -C /code/web-${Name} && \
rm -f /code/web-${Name}.tar.gz && \
rm -rf /code/web && \
ln -s /code/web-${Name} /code/web"
done
}
deploy () {
code_tar
scp_web
}
deploy
2. Jenkins配置
3. Git上传标签与更改的代码
3.1 更改html代码
3.2 提交代码
[root@gitlab ~/monitor]# git add .
[root@gitlab ~/monitor]# git commit -m "第一个版本"
[master 3d08826] 第一个版本
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab ~/monitor]# git push origin master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 316 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@gitlab.xts.com:xts/monitor.git
3a0533d..3d08826 master -> master
3.3 创建代码标签,并上传到git
[root@gitlab ~/monitor]# git tag -a "v1.1" -m "第一个版本" # 创建tag
[root@gitlab ~/monitor]# git tag # 查看tag
v1.1
[root@gitlab ~/monitor]# git push origin tag v1.1 # 上传tag
Counting objects: 1, done.
Writing objects: 100% (1/1), 171 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@gitlab.xts.com:xts/monitor.git
* [new tag] v1.1 -> v1.1
git仓库查看标签是否上传成功
此处再增加两个标签,分别为v1.2和v1.3,过程同上
4. Jenkins开始构建
4.1 Jenkins构建代码
4.2 浏览器验证
4.3 再次构建v1.2和v1.3
v1.2构建
v1.3构建
在web的站点目录下,也有会构建不同版本的记录(是否存在,根据脚本的内容而定)
5. 安装Git Parameter,以列表的形式选择发布版本
5.1 安装Git Parameter插件
两种安装方式
方式1:直接在Jenkins插件功能中获取安装
方式2:Jenkins官网(jenkins.io)下载插件,然后导入
5.2 配置Git Parameter
Jenkins通过Tag方式回滚代码
选择历史的发布版本,进行回滚(会导致web机器中有多份不同时间,但相同版本的代码)
回滚前的版本
回滚后的版本
方式2:在脚本中通过软连接方式实现,回滚时,软连接到回滚版本的代码
注意:该方式必须保证web站点目录下,相同的代码版本只有一份,否则回滚就会报错
清理站点目录下,多余的相同版本(后面会介绍,如何防止相同版本代码重复构建)
重新发布三个版本, 保证每个版本代码,只有一份
Tag排序方式乱,解决办法
编辑回滚脚本
[root@jenkins /scripts]# cp html_deploy_tag.sh html_deploy_tag_rollback.sh
[root@jenkins /scripts]# vim html_deploy_tag_rollback.sh
#!/usr/bin/bash
Date=$(date +%F-%H-%M)
web_server="192.168.1.92 192.168.1.93"
Name=${Date}-${Tag}
code_tar () {
cd /var/lib/jenkins/jobs/freestyle-monitor/workspace
tar czf /opt/web-${Name}.tar.gz ./*
}
scp_web () {
for host in $web_server
do
scp -r /opt/web-${Name}.tar.gz root@${host}:/code/
ssh root@${host} "mkdir -p /code/web-${Name} && \
tar xf /code/web-${Name}.tar.gz -C /code/web-${Name} && \
rm -f /code/web-${Name}.tar.gz && \
rm -rf /code/web && \
ln -s /code/web-${Name} /code/web"
done
}
back(){ # 新增加的内容
for host in $web_server
do
back_file=`ssh root@$host "find /code/ -maxdepth 1 -type d -name '*-${Tag}*'"` # -maxdepth 1,不显示查找出来的目录的子目录
ssh root@$host "rm -f /code/web &&\
ln -s ${back_file} /code/web"
done
}
deploy () {
code_tar
scp_web
}
if [ $deploy_env == "deploy" ] # 新增加的内容
then
deploy
elif [ $deploy_env == "rollback" ]
then
back
fi
Jenkins进行回滚配置
回滚前的版本
回滚后的版本
Jenkins防止重复构建(相同的版本多次发布)
相同的版本多次发布后,会造成回滚的时候出错
1. 使用Jenkins自带环境变量,编辑防重复构建脚本
2. 编辑脚本
[root@jenkins /scripts]# cat html_deploy_tag_rollback.sh
#!/usr/bin/bash
Date=$(date +%F-%H-%M)
web_server="192.168.1.92 192.168.1.93"
Name=${Date}-${Tag}
code_tar () {
cd /var/lib/jenkins/jobs/freestyle-monitor/workspace
tar czf /opt/web-${Name}.tar.gz ./*
}
scp_web () {
for host in $web_server
do
scp -r /opt/web-${Name}.tar.gz root@${host}:/code/
ssh root@${host} "mkdir -p /code/web-${Name} && \
tar xf /code/web-${Name}.tar.gz -C /code/web-${Name} && \
rm -f /code/web-${Name}.tar.gz && \
rm -rf /code/web && \
ln -s /code/web-${Name} /code/web"
done
}
back(){
for host in $web_server
do
back_file=`ssh root@$host "find /code/ -maxdepth 1 -type d -name '*-${Tag}*'"`
ssh root@$host "rm -f /code/web &&\
ln -s ${back_file} /code/web"
done
}
deploy () {
code_tar
scp_web
}
if [ $deploy_env == "deploy" ]
then
if [ $GIT_COMMIT == $GIT_PREVIOUS_SUCCESSFUL_COMMIT ] # 新增加一个判断
then
echo "${Tag}已经构建过了,无需重复构建。"
exit 1
fi # 判断结束
deploy
elif [ $deploy_env == "rollback" ]
then
back
fi
3. Jenkins测试重复构建能否成功
4. 创建V1.4发布,测试发布和回退功能是否正常
4.1 更改代码,添加tag
[root@gitlab ~]# vim monitor/index.html
[root@gitlab ~]# sed -n "43,1p" monitor/index.html
<a class="logo pull-left" href="index.html" style="width: 233px">移动能效管理平台-v1.4</a> # 更改的内容
[root@gitlab ~]#
[root@gitlab ~]# cd monitor/
[root@gitlab ~/monitor]# git add .
[root@gitlab ~/monitor]# git commit -m "第四个版本"
[master 45e66b3] 第四个版本
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab ~/monitor]# git push origin master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 320 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@gitlab.xts.com:xts/monitor.git
37e689f..45e66b3 master -> master
[root@gitlab ~/monitor]# git tag -a "v1.4" -m "第四个版本"
[root@gitlab ~/monitor]# git push origin tag v1.4
Counting objects: 1, done.
Writing objects: 100% (1/1), 171 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@gitlab.xts.com:xts/monitor.git
* [new tag] v1.4 -> v1.4
4.2 Jenkins发布新版本代码
4.3 回滚测试
回滚前版本
回滚后版本
Jenkins实现JAVA项目自动化上线
两种版本,有数据库和没有数据库
1. 无数据库的JAVA项目
1.1 什么才算是JAVA项目
简单来说,就是用JAVA工具编写的代码。
其中有三种名词需要了解:
(1)源码包:IDE工具编写
(2)JAR包:源码包需要编译,编译的过程中,代码依赖一些JAR包(最后形成了WAR包),
jar包还分为两种类型:只用来被依赖的和可独立运行的。
独立运行的如:java -jar xxx.jar
(3)WAR包:可部署
1.2 搭建一套JAVA集群部署代码
1.2.1 获取Tomcat安装包
1.2.2 在web集群上安装tomcat
web01
[root@web01 ~]# yum -y install java
[root@web01 ~]# mkdir /soft
[root@web01 ~]# tar zxf apache-tomcat-9.0.37.tar.gz -C /soft/
[root@web01 ~]# ln -s /soft/apache-tomcat-9.0.37 /soft/tomcat
[root@web01 ~]# ll /soft/tomcat
lrwxrwxrwx 1 root root 26 Aug 16 21:05 /soft/tomcat -> /soft/apache-tomcat-9.0.37
[root@web01 ~]# /soft/tomcat/bin/startup.sh
Using CATALINA_BASE: /soft/tomcat
Using CATALINA_HOME: /soft/tomcat
Using CATALINA_TMPDIR: /soft/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /soft/tomcat/bin/bootstrap.jar:/soft/tomcat/bin/tomcat-juli.jar
Tomcat started.
web02
[root@web02 ~]# yum -y install java
[root@web02 ~]# mkdir /soft
[root@web02 ~]# tar zxf apache-tomcat-9.0.37.tar.gz -C /soft/
[root@web02 ~]# ln -s /soft/apache-tomcat-9.0.37 /soft/tomcat
[root@web02 ~]# ll /soft/tomcat
lrwxrwxrwx 1 root root 26 Aug 16 21:05 /soft/tomcat -> /soft/apache-tomcat-9.0.37
[root@web02 ~]# /soft/tomcat/bin/startup.sh
Using CATALINA_BASE: /soft/tomcat
Using CATALINA_HOME: /soft/tomcat
Using CATALINA_TMPDIR: /soft/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /soft/tomcat/bin/bootstrap.jar:/soft/tomcat/bin/tomcat-juli.jar
Tomcat started.
1.2.2 配置nginx+Tomcat
web01
[root@web01 /etc/nginx/conf.d]# vim tomcat.xts.com.conf
[root@web01 /etc/nginx/conf.d]# cat tomcat.xts.com.conf
server {
listen 80;
server_name tomcat.xts.com;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
[root@web01 /etc/nginx/conf.d]# systemctl restart nginx
web02
[root@web02 /etc/nginx/conf.d]# vim tomcat.xts.com.conf
[root@web02 /etc/nginx/conf.d]# cat tomcat.xts.com.conf
server {
listen 80;
server_name tomcat.xts.com;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
[root@web02 /etc/nginx/conf.d]# systemctl restart nginx
1.2.3 nginx负载均衡接入tomcat
[root@lb01 ~]# vim /etc/nginx/conf.d/proxy_tomcat.xts.com.conf
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_tomcat.xts.com.conf
upstream java {
server 192.168.1.92:80;
server 192.168.1.93:80;
}
server {
listen 80;
server_name tomcat.xts.com;
location / {
proxy_pass http://java;
proxy_set_header Host $http_host;
}
}
[root@lb01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lb01 ~]# systemctl restart nginx
在宿主机做host解析,然后浏览器访问
# 把下面的内容,添加到hosts文件中
192.168.1.91 tomcat.xts.com
2. 实现JAVA项目手动上线
2.1 编写java代码
上传准备好的java代码包
java代码包下载点我
提取码:maek
[root@gitlab ~]# tar zxf hello-world-war.tar.gz
[root@gitlab ~]# ll
total 13580
-rw-------. 1 root root 1487 Oct 3 2019 anaconda-ks.cfg
drwxr-xr-x 3 root root 96 Jun 23 07:13 demo
drwxr-xr-x 5 root root 91 Aug 6 2019 hello-world-war
-rw-r--r-- 1 root root 14141 Jan 30 2020 hello-world-war.tar.gz
drwxr-xr-x 9 root root 4096 Aug 16 18:27 monitor
-rw-r--r-- 1 root root 13881292 Jan 30 2020 monitor_html.tar.gz
[root@gitlab ~]#
[root@gitlab ~]# cd hello-world-war/
[root@gitlab ~/hello-world-war]# ls
dist pom.xml README.md src # 这些就是源码包
2.2 将java项目推送至gitlab仓库
[root@gitlab ~/hello-world-war]# git remote remove origin
[root@gitlab ~/hello-world-war]# git remote add origin git@gitlab.xts.com:xts/hello-java.git
[root@gitlab ~/hello-world-war]# git add .
[root@gitlab ~/hello-world-war]# git commit -m "java项目"
[master 94e39fd] java项目
1 file changed, 2 insertions(+), 2 deletions(-)
[root@gitlab ~/hello-world-war]# git push origin master
Counting objects: 19, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (19/19), 3.38 KiB | 0 bytes/s, done.
Total 19 (delta 2), reused 0 (delta 0)
To git@gitlab.xts.com:xts/hello-java.git
* [new branch] master -> master
2.3 手动拉取java源代码
克隆新添加的git仓库
[root@jenkins ~]# git clone git@gitlab.xts.com:xts/hello-java.git
Cloning into 'hello-java'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 19 (delta 2), reused 0 (delta 0)
Receiving objects: 100% (19/19), done.
Resolving deltas: 100% (2/2), done.
[root@jenkins ~]# ls
anaconda-ks.cfg hello-java jenkins-2.176.1-1.1.noarch.rpm jenkins_2.176_plugins.tar.gz
[root@jenkins ~]# cd hello-java/
[root@jenkins ~/hello-java]#
[root@jenkins ~/hello-java]# ll
total 8
drwxr-xr-x 2 root root 29 Aug 16 22:03 dist
-rw-r--r-- 1 root root 930 Aug 16 22:03 pom.xml
-rw-r--r-- 1 root root 213 Aug 16 22:03 README.md
drwxr-xr-x 3 root root 18 Aug 16 22:03 src
# 由于是java源码,所以需要安装maven工具(yum安装(版本低)和二进制安装(版本高),二进制安装解压即用)
[root@jenkins ~/hello-java]# yum -y install java maven
更换maven默认的下载源,国外换到国内
[root@jenkins ~]# rpm -ql maven|grep settings.xml
/etc/maven/settings.xml
/usr/share/maven/conf/settings.xml
[root@jenkins ~]# vim /etc/maven/settings.xml
# 在vim中/mirrors,然后在</mirrors>的上面添加如下内容
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
2.4 对源代码进行编译(使用工具maven对源代码进行编译,生成war包)
root@jenkins ~/hello-java]# mvn package
……省略部分输出
[INFO] Packaging webapp
[INFO] Assembling webapp [hello-world-war] in [/root/hello-java/target/hello-world-war-1.0.0]
[INFO] Processing war project
[INFO] Copying webapp resources [/root/hello-java/src/main/webapp]
[INFO] Webapp assembled in [37 msecs]
[INFO] Building war: /root/hello-java/target/hello-world-war-1.0.0.war # 这就是编译完成的包,scp就是把这个包推送到web集群
[INFO] WEB-INF/web.xml already added, skipping
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2:02.948s
[INFO] Finished at: Sun Aug 16 22:31:50 CST 2020
[INFO] Final Memory: 12M/130M
[INFO] ------------------------------------------------------------------------
2.5 通过scp方式将编译好的war包推送至web集群
清空/soft/tomcat/webapps目录下的所有内容
# web01
[root@web01 /soft/tomcat/webapps]# rm -rf *
[root@web01 /soft/tomcat/webapps]# ls
[root@web01 /soft/tomcat/webapps]#
# web02
[root@web02 /etc/nginx/conf.d]# cd /soft/tomcat/webapps
[root@web02 /soft/tomcat/webapps]# rm -rf *
[root@web02 /soft/tomcat/webapps]# ls
手动推送编译好的war包到web集群
[root@jenkins ~/hello-java]# for host in 92 93;do scp target/*.war root@192.168.1.${host}:/soft/tomcat/webapps/ROOT.war;done
hello-world-war-1.0.0.war 100% 2405 2.3MB/s 00:00
hello-world-war-1.0.0.war 100% 2405 1.9MB/s 00:00
# web集群查看是否收到推送的包
[root@web01 /soft/tomcat/webapps]# ll
total 4
drwxr-x--- 4 root root 54 Aug 16 22:41 ROOT
-rw-r--r-- 1 root root 2405 Aug 16 22:41 ROOT.war
[root@web02 /soft/tomcat/webapps]# ll
total 4
drwxr-x--- 4 root root 54 Aug 16 22:41 ROOT
-rw-r--r-- 1 root root 2405 Aug 16 22:41 ROOT.war
2.6 重启tomcat服务
[root@jenkins ~/hello-java]# for tomcat in 92 93;do ssh root@192.168.1.${tomcat} "pkill -9 java && /soft/tomcat/bin/startup.sh";done # 正常情况下,建议先使用shutdown.sh停止,然后检查进程是否还残存,然后在startup.sh
Tomcat started.
Tomcat started.
# 查看是否有多余的tomcat进程(正常1个)
[root@web01 /soft/tomcat/webapps]# ps -ef | grep [t]omcat
root 7158 1 7 22:45 ? 00:00:05 /usr/bin/java -Djava.util.logging.config.file=/soft/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /soft/tomcat/bin/bootstrap.jar:/soft/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/soft/tomcat -Dcatalina.home=/soft/tomcat -Djava.io.tmpdir=/soft/tomcat/temp org.apache.catalina.startup.Bootstrap start
[root@web02 /soft/tomcat/webapps]# ps -ef |grep [t]omcat
root 7116 1 4 22:45 ? 00:00:06 /usr/bin/java -Djava.util.logging.config.file=/soft/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /soft/tomcat/bin/bootstrap.jar:/soft/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/soft/tomcat -Dcatalina.home=/soft/tomcat -Djava.io.tmpdir=/soft/tomcat/temp org.apache.catalina.startup.Bootstrap start
2.7 浏览器访问
3. 实现JAVA项目自动上线
3.1 新建maven项目()
所需插件
新建java项目
3.2 jenkins调用maven进行编译(构建)
3.2.1 告诉jenkins,maven安装位置
3.2.2 告诉jenkins,jdk的安装位置
测试构建
3.3 jenkins调用shell实现tag上线
3.3.1 编写shell脚本
[root@jenkins ~]# cd /scripts/
[root@jenkins /scripts]# cp html_deploy_tag.sh java_deploy_tag.sh
[root@jenkins /scripts]# vim java_deploy_tag.sh
#!/usr/bin/bash
Date=$(date +%F-%H-%M)
web_server="192.168.1.92 192.168.1.93"
NAME=${Date}-${git_version}
code_tar () {
cd ${WORKSPACE}
}
scp_web () {
for host in $web_server
do
scp -r target/*.war root@${host}:/opt/ROOT-${NAME}.war
ssh root@${host} "mkdir -p /opt/ROOT-${NAME} && \
unzip /opt/ROOT-${NAME}.war -d /opt/ROOT-${NAME} && \
rm -f /opt/ROOT-${NAME}.war && \
rm -rf /soft/tomcat/webapps/ROOT && \
ln -s /opt/ROOT-${NAME} /soft/tomcat/webapps/ROOT && \
pkill -9 java && \ # 这里在生产环境上,必须写if语句,来判断进程和端口是否存在。由于是学习环境,所以省略的判断步骤
/soft/tomcat/bin/startup.sh"
done
}
deploy () {
code_tar
scp_web
}
deploy
# 清除web机器上之前测试留下的ROOT.war
rm -rf /soft/tomcat/webapps/*.war
3.3.2 添加jenkins参数化构建
3.3.3 配置默认构建的分支
3.3.4 配置脚本
3.3.5 上传java项目所需tag
[root@gitlab ~]#
[root@gitlab ~]# cd hello-world-war/
[root@gitlab ~/hello-world-war]# vim src/main/webapp/index.jsp
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h1>Hello World! Oldxie - v1.1</h1> # 在Hello World! Oldxie后面添加 - v1.1,方便后面测试
<p>
It is now
<%= new java.util.Date() %></p>
<p>
You are coming from
<%= request.getRemoteAddr() %></p>
</body>
# 提交修改后的代码
[root@gitlab ~/hello-world-war]# git add .
[root@gitlab ~/hello-world-war]# git commit -m "java的第一个版本"
[master ee1cc3c] java的第一个版本
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab ~/hello-world-war]# git push origin master
Counting objects: 11, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 471 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To git@gitlab.xts.com:xts/hello-java.git
94e39fd..ee1cc3c master -> master
# 新增tag
[root@gitlab ~/hello-world-war]# git tag -a "v1.1" -m "java的第一个版本"
[root@gitlab ~/hello-world-war]# git push origin v1.1
Counting objects: 1, done.
Writing objects: 100% (1/1), 178 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@gitlab.xts.com:xts/hello-java.git
* [new tag] v1.1 -> v1.1
3.3.6 开始构建测试
3.3.7 访问测试
3.3.8 查看web机器上面软连接的情况
3.3.9 为什么不直接把ROOT.war直接推送到tomcat的webapps目录下
当webapps目录下有多个文件时,会逐个进行加载,这样就会影响整个项目的启动速度。
随着时间的推移,可能该目录下的文件会越来越多,这个时候,可以使用find命令进行删除(方法很多)。
3.4 jenkins调用SHELL实现tag回退
3.4.1 清理web服务器上多余的代码文件
3.4.2 编辑回退脚本
[root@jenkins ~]# cd /scripts/
[root@jenkins /scripts]# cp java_deploy_tag.sh java_deploy_rollback.sh
[root@jenkins /scripts]# vim java_deploy_rollback.sh
#!/usr/bin/bash
Date=$(date +%F-%H-%M)
web_server="192.168.1.92 192.168.1.93"
NAME=${Date}-${git_version}
code_tar () {
cd ${WORKSPACE}
}
scp_web () {
for host in $web_server
do
scp -r target/*.war root@${host}:/opt/ROOT-${NAME}.war
ssh root@${host} "mkdir -p /opt/ROOT-${NAME} && \
unzip /opt/ROOT-${NAME}.war -d /opt/ROOT-${NAME} && \
rm -f /opt/ROOT-${NAME}.war && \
rm -rf /soft/tomcat/webapps/ROOT && \
ln -s /opt/ROOT-${NAME} /soft/tomcat/webapps/ROOT && \
pkill -9 java && \
/soft/tomcat/bin/startup.sh"
done
}
back () { # 新增的回退部分
for host in $web_server
do
back_file=$(ssh root@${host} "find /opt/ -maxdepth 1 -type d -name "ROOT-*-${git_version}*"")
ssh root@$host "rm -f /soft/tomcat/webapps/ROOT && \
ln -s $back_file /soft/tomcat/webapps/ROOT && \
pkill -9 java && \
/soft/tomcat/bin/startup.sh"
done
}
deploy () {
code_tar
scp_web
}
if [ $deploy_env == "deploy" ] # 新增的判断,这里需要去jenkins web页面中添加一个选项配置,让$deploy_env变量生效
then
if [ $GIT_COMMIT == $GIT_PREVIOUS_SUCCESSFUL_COMMIT ] # 这个判断,防止相同版本重复构建
then
echo "${$Tag}已经构建过了,无需重复构建。"
exit 1
fi
deploy
elif [ $deploy_env == "rollback" ]
then
back
fi
3.4.3 jenkins中添加选项参数(choice parameter)
3.4.4 构建测试
编辑代码文件,更改版本为v1.2
提交代码和tag
[root@gitlab ~]# cd hello-world-war/
[root@gitlab ~/hello-world-war]# git add .
[root@gitlab ~/hello-world-war]# git commit -m "第二个版本"
[master a08bc3f] 第二个版本
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab ~/hello-world-war]# git push origin master
Counting objects: 11, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 457 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 0 (delta 0)
remote: GitLab: API is not accessible
To git@gitlab.xts.com:xts/hello-java.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@gitlab.xts.com:xts/hello-java.git'
[root@gitlab ~/hello-world-war]# git tag -a "v1.2" -m "第二个版本"
[root@gitlab ~/hello-world-war]# git push origin v1.2
Counting objects: 12, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 597 bytes | 0 bytes/s, done.
Total 7 (delta 2), reused 0 (delta 0)
To git@gitlab.xts.com:xts/hello-java.git
* [new tag] v1.2 -> v1.2
构建测试
3.4.4 版本回退
3.4.5 防重复构建测试
Jenkins实现JAVA项目自动化上线(有数据库)
手动部署CMS项目
1. 准备数据库
这里可以选择yum安装或者二进制安装,二进制安装请参考下面链接中的步骤
二进制安装MySQL
2. 准备好项目代码CMS(开发下项目)
CMS下载点我
提取码:4adt
[root@gitlab ~]# rz -E # 上传代码包
rz waiting to receive.
[root@gitlab ~]# ll
total 132456
-rw-------. 1 root root 1487 Oct 3 2019 anaconda-ks.cfg
-rw-r--r-- 1 root root 121728016 Jan 30 2020 cms-war-new.tar.gz # cms代码包
drwxr-xr-x 3 root root 96 Jun 23 07:13 demo
drwxr-xr-x 5 root root 91 Aug 6 2019 hello-world-war
-rw-r--r-- 1 root root 14141 Jan 30 2020 hello-world-war.tar.gz
drwxr-xr-x 9 root root 4096 Aug 16 18:27 monitor
-rw-r--r-- 1 root root 13881292 Jan 30 2020 monitor_html.tar.gz
[root@gitlab ~]# tar zxf cms-war-new.tar.gz
[root@gitlab ~]# cd cms-war/
[root@gitlab ~/cms-war]# ll
total 40
drwxr-xr-x 2 root root 140 Aug 29 2019 else
-rw-r--r-- 1 root root 11358 Aug 28 2019 LICENSE
-rwxr-xr-x 1 root root 12430 Aug 28 2019 pom.xml
-rw-r--r-- 1 root root 10923 Aug 28 2019 README.md
drwxr-xr-x 3 root root 18 Aug 28 2019 src
[root@gitlab ~/cms-war]#
3. 上传项目代码至gitlab中
3.1 在gitlab中新建项目
3.2 新建仓库
[root@gitlab ~/cms-war]# git remote -v
origin https://gitee.com/mail_osc/wangmarket.git (fetch)
origin https://gitee.com/mail_osc/wangmarket.git (push)
[root@gitlab ~/cms-war]# git remote remove origin
[root@gitlab ~/cms-war]# git remote add origin git@gitlab.xts.com:xts/cms.git
[root@gitlab ~/cms-war]# git add .
warning: You ran 'git add' with neither '-A (--all)' or '--ignore-removal',
whose behaviour will change in Git 2.0 with respect to paths you removed.
Paths like 'src/main/webapp/WEB-INF/view/iw/install/accessKey.jsp' that are
removed from your working tree are ignored with this version of Git.
* 'git add --ignore-removal <pathspec>', which is the current default,
ignores paths you removed from your working tree.
* 'git add --all <pathspec>' will let you also record the removals.
Run 'git status' to check the paths you removed from your working tree.
[root@gitlab ~/cms-war]# git commit -m "Initial commit"
[master c9d0f85] Initial commit
4 files changed, 1166 insertions(+), 13 deletions(-)
create mode 100755 else/new.sql
[root@gitlab ~/cms-war]# git push -u origin master
Counting objects: 7975, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3082/3082), done.
Writing objects: 100% (7975/7975), 108.40 MiB | 18.50 MiB/s, done.
Total 7975 (delta 4205), reused 7953 (delta 4196)
remote: Resolving deltas: 100% (4205/4205), done.
To git@gitlab.xts.com:xts/cms.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
[root@gitlab ~/cms-war]#
4. 手动拉取cms项目代码
[root@jenkins ~]# git clone git@gitlab.xts.com:xts/cms.git
Cloning into 'cms'...
remote: Enumerating objects: 7975, done.
remote: Counting objects: 100% (7975/7975), done.
remote: Compressing objects: 100% (3073/3073), done.
remote: Total 7975 (delta 4205), reused 7975 (delta 4205)
Receiving objects: 100% (7975/7975), 108.40 MiB | 20.89 MiB/s, done.
Resolving deltas: 100% (4205/4205), done.
[root@jenkins ~]# ls
anaconda-ks.cfg cms hello-java jenkins-2.176.1-1.1.noarch.rpm jenkins_2.176_plugins.tar.gz
[root@jenkins ~]# cd cms/
[root@jenkins ~/cms]# ll
total 40
drwxr-xr-x 2 root root 140 Sep 3 22:21 else
-rw-r--r-- 1 root root 11358 Sep 3 22:21 LICENSE
-rwxr-xr-x 1 root root 12430 Sep 3 22:21 pom.xml
-rw-r--r-- 1 root root 10923 Sep 3 22:21 README.md
drwxr-xr-x 3 root root 18 Sep 3 22:21 src
[root@jenkins ~/cms]#
5. 导入SQL语句到数据库中
5.1 添加用户
3306 [(none)]>grant all privileges on *.* to root@'%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
5.2 导入SQL
# 安装mysql客户端
[root@gitlab ~/cms-war/else]# yum -y install mariadb
[root@gitlab ~/cms-war/else]# ll
total 216
-rw-r--r-- 1 root root 4638 Aug 28 2019 instructions.md
-rw-r--r-- 1 root root 3665 Aug 28 2019 markdown
-rwxr-xr-x 1 root root 73905 Aug 28 2019 new.sql # 需要导入的sql
-rw-r--r-- 1 root root 4710 Aug 28 2019 pc_wap_tag
-rw-r--r-- 1 root root 2293 Aug 28 2019 quickConfig.md
-rw-r--r-- 1 root root 45888 Aug 28 2019 upgradeLog
-rw-r--r-- 1 root root 65947 Aug 28 2019 wangmarket.sql
[root@gitlab ~/cms-war/else]# cat new.sql | mysql -h 192.168.1.61 -u root -p
Enter password:
[root@gitlab ~/cms-war/else]#
# 数据库查看
3306 [(none)]>show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
| wangmarket | # 新添加的数据库
| world |
+--------------------+
7 rows in set (0.00 sec)
6. 修改数据库的配置信息
[root@jenkins ~/cms]# vim src/main/resources/application.properties
把里面数据库的IP改成自己数据库的IP
7. 使用maven进行编译
该编译时间大约3到6分钟左右
[root@jenkins ~/cms]# mvn clean package -Dmaven.test.skip=true
[root@jenkins ~/cms]# ll
total 40
drwxr-xr-x 2 root root 140 Sep 3 22:21 else
-rw-r--r-- 1 root root 11358 Sep 3 22:21 LICENSE
-rwxr-xr-x 1 root root 12430 Sep 3 22:21 pom.xml
-rw-r--r-- 1 root root 10923 Sep 3 22:21 README.md
drwxr-xr-x 3 root root 18 Sep 3 22:21 src
drwxr-xr-x 7 root root 159 Sep 3 22:42 target # 编译完成后,会生成该目录
[root@jenkins ~/cms]# ll target/
total 136124
drwxr-xr-x 6 root root 4096 Sep 3 22:40 classes
drwxr-xr-x 3 root root 25 Sep 3 22:40 generated-sources
drwxr-xr-x 2 root root 28 Sep 3 22:40 maven-archiver
drwxr-xr-x 3 root root 35 Sep 3 22:40 maven-status
drwxr-xr-x 8 root root 139 Sep 3 22:40 wangmarket
-rw-r--r-- 1 root root 75482422 Sep 3 22:42 wangmarket.war # 生成的war包
-rw-r--r-- 1 root root 63900676 Sep 3 22:40 wangmarket.war.original
8. 把war包传输到web机器上
8.1 清理环境
# web01
[root@web01 /soft/tomcat/webapps]# ls
ROOT
[root@web01 /soft/tomcat/webapps]# rm -f ROOT
[root@web01 /soft/tomcat/webapps]#
# web02
[root@web02 ~]# cd /soft/tomcat/webapps/
[root@web02 /soft/tomcat/webapps]# ls
ROOT
[root@web02 /soft/tomcat/webapps]# rm -f ROOT
[root@web02 /soft/tomcat/webapps]#
8.2 传输war包
[root@jenkins ~/cms]# for i in 92 93;do scp target/*.war root@192.168.1.${i}:/soft/tomcat/webapps/ROOT.war;done
wangmarket.war 100% 72MB 71.9MB/s 00:01
wangmarket.war 100% 72MB 71.9MB/s 00:01
# 传输后检查
## web01
[root@web01 /soft/tomcat/webapps]# ll
total 73716
drwxr-x--- 9 root root 150 Sep 3 23:00 ROOT
-rw-r--r-- 1 root root 75482422 Sep 3 23:00 ROOT.war
## web02
[root@web02 /soft/tomcat/webapps]# ll
total 73716
drwxr-x--- 9 root root 150 Sep 3 23:00 ROOT
-rw-r--r-- 1 root root 75482422 Sep 3 23:00 ROOT.war
# 重启tomcat
## web01
[root@web01 /soft/tomcat/webapps]# pkill -9 java
[root@web01 /soft/tomcat/webapps]# /soft/tomcat/bin/startup.sh
Using CATALINA_BASE: /soft/tomcat
Using CATALINA_HOME: /soft/tomcat
Using CATALINA_TMPDIR: /soft/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /soft/tomcat/bin/bootstrap.jar:/soft/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@web01 /soft/tomcat/webapps]#
## web02
[root@web02 /soft/tomcat/webapps]# pkill -9 java
[root@web02 /soft/tomcat/webapps]# /soft/tomcat/bin/startup.sh
Using CATALINA_BASE: /soft/tomcat
Using CATALINA_HOME: /soft/tomcat
Using CATALINA_TMPDIR: /soft/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /soft/tomcat/bin/bootstrap.jar:/soft/tomcat/bin/tomcat-juli.jar
Tomcat started.
8.3 访问测试
停掉一台web
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_html.xts.com.conf
upstream html {
#server 192.168.1.92:80; # 随便注释掉一台,然后重新访问登录
server 192.168.1.93:80;
}
server {
listen 80;
server_name html.xts.com;
location / {
proxy_pass http://html;
proxy_set_header Host $http_host;
}
}
[root@lb01 ~]# systemctl restart nginx # 改完配置文件后,重启nginx使得配置生效
注意用无痕浏览模式
然后重新把注释的web给重新添加回来,再次访问,又会出现刚开始的问题,这个时候地址栏URL的后面,跟了一行字符串,session,一直没有变化,原因就是会话没有保持
解决办法,在负载均衡机器的nginx配置文件中添加ip_hash,做会话保持
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_html.xts.com.conf
upstream html {
ip_hash; # 添加ip_hash
server 192.168.1.92:80;
server 192.168.1.93:80;
}
server {
listen 80;
server_name html.xts.com;
location / {
proxy_pass http://html;
proxy_set_header Host $http_host;
}
}
[root@lb01 ~]# systemctl restart nginx
重新登录
自动部署CMS项目
自动部署思路
(1)Jenkins自动拉取cms项目代码
(2)Jenkins配置构建前操作(将数据库的配置文件拷贝至源码中)
(3)Jenkins调用maven进行编译
(4)Jenkins调用shell,推送war包至web集群,重启tomcat
(5)用户测试访问
1. 新建任务
2. git上传tag
[root@gitlab ~/cms-war]# git tag -a v1.1 -m "cms"
[root@gitlab ~/cms-war]# git push origin tag v1.1
Counting objects: 1, done.
Writing objects: 100% (1/1), 149 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@gitlab.xts.com:xts/cms.git
* [new tag] v1.1 -> v1.1
[root@gitlab ~/cms-war]#
3. 清理web环境
# web01
[root@web01 /soft/tomcat/webapps]# rm -rf *
[root@web01 /soft/tomcat/webapps]# ls
[root@web01 /soft/tomcat/webapps]#
# web02
[root@web02 /soft/tomcat/webapps]# rm -rf *
[root@web02 /soft/tomcat/webapps]# ls
[root@web02 /soft/tomcat/webapps]#
4. 构建测试
5. 访问测试
这里之所以会404,是因为我们cms项目,关于数据库的配置没有更改,还有就是Tomcat原生项目不支持软连接。解决办法如下:
(1)软连接问题
tomcat567版本:在tomcat里context.xml文件里设置
<Context allowLinking="true" />
tomcat89版本: 在tomcat里context.xml文件里设置
<Context>
<Resources allowLinking="true" />
</Context>
我们这里用的是tomcat9.所以采用第二个配置
# web01
[root@web01 ~]# vim /soft/tomcat/conf/context.xml
# 在大约19行,<Context>的下面加上如下配置
<Resources allowLinking="true" />
[root@web01 ~]# !pk
pkill -9 java
[root@web01 ~]# /soft/tomcat/bin/startup.sh
Using CATALINA_BASE: /soft/tomcat
Using CATALINA_HOME: /soft/tomcat
Using CATALINA_TMPDIR: /soft/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /soft/tomcat/bin/bootstrap.jar:/soft/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@web01 ~]#
# web02
[root@web02 ~]# vim /soft/tomcat/conf/context.xml
# 在大约19行,<Context>的下面加上如下配置
<Resources allowLinking="true" />
[root@web02 ~]# !pk
pkill -9 java
[root@web02 ~]# /soft/tomcat/bin/startup.sh
Using CATALINA_BASE: /soft/tomcat
Using CATALINA_HOME: /soft/tomcat
Using CATALINA_TMPDIR: /soft/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /soft/tomcat/bin/bootstrap.jar:/soft/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@web02 ~]#
(2)数据库配置问题
[root@jenkins /scripts]# mv /opt/application.properties ./
[root@jenkins /scripts]# ll /scripts/application.properties
-rwxr-xr-x 1 root root 2886 Sep 6 17:31
(3)构建,并访问
测试:构建一个新的版本
(1)修改代码
[root@gitlab ~]# cd cms-war/
[root@gitlab ~/cms-war]# git pull origin master # 因为刚刚在git仓库中删除了applicaiotn文件,所以之这里需要同步一下代码文件到本地
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 11 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From gitlab.xts.com:xts/cms
* branch master -> FETCH_HEAD
Updating c9d0f85..6a31eeb
Fast-forward
src/main/resources/application.properties | 71 ------------------------
1 file changed, 71 deletions(-)
delete mode 100755 src/main/resources/application.properties
[root@gitlab ~/cms-war]#
[root@gitlab ~/cms-war]# git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
# (use "git push" to publish your local commits)
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: src/main/webapp/WEB-INF/view/iw_update/login/login.jsp
#
# Changes not staged for commit:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: src/main/webapp/WEB-INF/view/iw/install/accessKey.jsp
# deleted: src/main/webapp/WEB-INF/view/iw/install/index.jsp
# deleted: src/main/webapp/WEB-INF/view/iw/install/installSuccess.jsp
#
[root@gitlab ~/cms-war]# git checkout .
[root@gitlab ~/cms-war]# vim src/main/webapp/WEB-INF/view/iw_update/login/login.jsp # 修改配置文件内容
# 61行
<%=Global.get("SITE_NAME") %> Oldxu 平台登陆系统
#改成
<%=Global.get("SITE_NAME") %> Oldxu-v2.0 平台登陆系统
[root@gitlab ~/cms-war]# git add .
[root@gitlab ~/cms-war]# git commit -m "v2.0"
[master 7b1d515] v2.0
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab ~/cms-war]# git push origin master
Counting objects: 19, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (10/10), 685 bytes | 0 bytes/s, done.
Total 10 (delta 6), reused 0 (delta 0)
To git@gitlab.xts.com:xts/cms.git
6a31eeb..7b1d515 master -> master
[root@gitlab ~/cms-war]# git tag -a v2.0 -m "v2.0"
[root@gitlab ~/cms-war]# git push origin tag v2.0
Counting objects: 1, done.
Writing objects: 100% (1/1), 148 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@gitlab.xts.com:xts/cms.git
* [new tag] v2.0 -> v2.0
(2)再次构建并访问
Sonarqube,代码质量检测
1. 什么是Sonarqube
Sonarqube是用来做代码质量扫描的,主要用于分析bug、漏洞、代码规范性。
2. 安装Sonarqube
2.1 准备环境
# Sonarqube是基于java开发的,所以需要依赖java环境。
# Sonarqube可以单独运行,也可以跟Jenkins集成在一起使用。
# 还需要mysql 5.6及以上版本的数据库。
# 这里需要准备一台新的机器,来安装Sonarqube。
[root@sonarqube ~]# yum -y install java
2.2 导入安装Sonarqube需要的包
Sonarqube包下载点我
提取码:u2qu
[root@sonarqube ~]# mkdir /sonarqube
[root@sonarqube ~]# cd /sonarqube
[root@sonarqube /sonarqube]# rz -E
rz waiting to receive.
[root@sonarqube /sonarqube]# ll
total 318008
-rw-r--r-- 1 root root 20515804 Jan 30 2020 mysql-community-client-5.6.45-2.el7.x86_64.rpm
-rw-r--r-- 1 root root 263300 Jan 30 2020 mysql-community-common-5.6.45-2.el7.x86_64.rpm
-rw-r--r-- 1 root root 2130748 Jan 30 2020 mysql-community-libs-5.6.45-2.el7.x86_64.rpm
-rw-r--r-- 1 root root 62561972 Jan 30 2020 mysql-community-server-5.6.45-2.el7.x86_64.rpm
-rw-r--r-- 1 root root 42051685 Jan 30 2020 sonar_plugins.tar.gz
-rw-r--r-- 1 root root 155709573 Jan 30 2020 sonarqube-7.0.zip
-rw-r--r-- 1 root root 42392358 Jan 30 2020 sonar-scanner-cli-4.0.0.1744-linux.zip
2.3 安装MySQL并创建sonar库
[root@sonarqube /sonarqube]# yum -y localinstall mysql-community-*.rpm
[root@sonarqube /sonarqube]# systemctl enable mysqld
[root@sonarqube /sonarqube]# systemctl start mysqld
[root@sonarqube /sonarqube]# mysqladmin password '123456'
Warning: Using a password on the command line interface can be insecure.
[root@sonarqube /sonarqube]# mysql -uroot -p123456 -e "create database sonar charset utf8;"
Warning: Using a password on the command line interface can be insecure.
2.3 安装Sonarqube
[root@sonarqube /sonarqube]# unzip sonarqube-7.0.zip -d /usr/local/
[root@sonarqube /sonarqube]# ln -s /usr/local/sonarqube-7.0/ /usr/local/sonarqube
[root@sonarqube /sonarqube]# ll /usr/local/sonarqube
lrwxrwxrwx 1 root root 25 Sep 7 00:51 /usr/local/sonarqube -> /usr/local/sonarqube-7.0/
[root@sonarqube /sonarqube]# vim /usr/local/sonarqube/conf/sonar.properties
# 在该文件中取消注释或加入这几行
sonar.jdbc.username=root
sonar.jdbc.password=123456
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
# Sonarqube不能用root用户启动,不然就报错,所以这里添加一个普通用户
[root@sonarqube ~]# useradd sonar
[root@sonarqube ~]# chown -R sonar. /usr/local/sonarqube-7.0/
# 启动
[root@sonarqube ~]# su - sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start"
Starting SonarQube...
Started SonarQube.
[root@sonarqube ~]# netstat -lntup | grep 9000
tcp6 0 0 :::9000 :::* LISTEN 7384/java
2.4 浏览器访问Sonarqube
在宿主机hosts添加域名解析
192.168.1.60 xts.sonar.com
2.5 登录Sonarqube
用户名密码都是:admin
3. 安装Sonarqube所需的插件(包括汉化)
Sonarqube进行扫描的时候,都是根据自身的插件去进行扫描的。
话句话说,需要扫描什么语言,就安装什么插件。
汉化插件
js插件
java插件
html插件
css插件
xml等
3.1 安装插件
[root@sonarqube /sonarqube]# tar tf sonar_plugins.tar.gz # 这个包是准备好的插件包
plugins/
plugins/README.txt
plugins/sonar-scm-git-plugin-1.3.0.869.jar
plugins/sonar-python-plugin-1.9.0.2010.jar
plugins/sonar-javascript-plugin-4.0.0.5862.jar
plugins/sonar-scm-svn-plugin-1.6.0.860.jar
plugins/sonar-l10n-zh-plugin-1.20.jar
plugins/sonar-html-plugin-3.0.1.1444.jar
plugins/sonar-csharp-plugin-7.3.0.5690.jar
plugins/sonar-flex-plugin-2.5.1.1831.jar
plugins/sonar-typescript-plugin-1.9.0.3766.jar
plugins/sonar-php-plugin-3.0.0.4537.jar
plugins/sonar-java-plugin-5.6.0.15032.jar
plugins/sonar-xml-plugin-2.0.1.2020.jar
plugins/sonar-css-plugin-1.1.1.1010.jar
[root@sonarqube /sonarqube]# mv /usr/local/sonarqube/extensions/plugins{,_bak} # 备份原来的插件目录
[root@sonarqube /sonarqube]# tar zxf sonar_plugins.tar.gz -C /usr/local/sonarqube/extensions/ # 解压我们准备好的插件包到这个目录
[root@sonarqube /sonarqube]# ll /usr/local/sonarqube/extensions/
total 8
drwxr-xr-x 2 sonar sonar 6 Sep 7 00:58 downloads
drwxr-xr-x 3 sonar sonar 20 Feb 2 2018 jdbc-driver
drwxr-xr-x 2 sonar sonar 4096 Aug 4 2019 plugins
drwxr-xr-x 2 sonar sonar 4096 Sep 7 00:58 plugins_bak # 原插件目录
# 重启sonar
[root@sonarqube ~]# su - sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart"
3.2 开启用户强制认证(不然加了token和没加一样)
4. 手动推送代码至Sonarqube进行分析
Sonarqube是使用客户端来推送代码到服务端的
4.1 安装客户端
[root@sonarqube /sonarqube]# scp sonar-scanner-cli-4.0.0.1744-linux.zip 192.168.1.62:/root
# jenkins上安装客户端
[root@jenkins ~]# unzip sonar-scanner-cli-4.0.0.1744-linux.zip -d /usr/local/
[root@jenkins ~]# ln -s /usr/local/sonar-scanner-4.0.0.1744-linux /usr/local/sonar-scanner
# 更改配置文件,指定服务端地址
[root@jenkins ~]# cat /usr/local/sonar-scanner/conf/sonar-scanner.properties
#Configure here general information about the environment, such as SonarQube server connection details for example
#No information about specific project should appear here
#----- Default SonarQube server
sonar.host.url=http://xts.sonar.com:9000 # 修改这一样,取消注释,然后把rul替换一下
sonar.login=c5521a109d413bd5ef491bf009b28ab24c6846a6 # 然后添加上这一行,=等号后面的值,是刚开始安装完毕后,出现的token
#----- Default source code encoding
sonar.sourceEncoding=UTF-8 # 取消这行注释
# 添加hosts解析
[root@jenkins ~]# vim /etc/hosts
192.168.1.60 xts.sonar.com
4.2 分析代码
# 开始分析代码
[root@jenkins /var/lib/jenkins/jobs/freestyle-monitor/workspace]# /usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=html -Dsonar.sources=.
# 等待一会儿后,出现下面的内容。就可以去浏览器看了结果了
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 50.126s
INFO: Final Memory: 13M/50M
INFO: ------------------------------------------------------------------------
坏味道就是不规范的代码
4. Jenkins集成Sonarqube
4.1 Jenkins安装Sonarqube插件
插件名称:SonarQube Scanner
4.2 告诉Jenkins,Sonarqube服务端安装位置
如果忘记了token,可以如下重新申请:
4.3 告诉Jenkins,Sonar-scanner客户端安装位置
uploading-image-299532.png
客户端是配置在jenkins上的,所以要去jenkins上找
[root@jenkins ~]# ll # 复制这个路径到jenkins中
lrwxrwxrwx 1 root root 41 Sep 7 08:56 /usr/local/sonar-scanner -> /usr/local/sonar-scanner-4.0.0.1744-linux
4.4 改造项目,支持Sonarqube自动扫描
需要配置的参数
sonar.projectName=${JOB_NAME} # 项目在sonarqube上显示的名称
sonar.projectKey=html # 项目唯一标识,不能重复
sonar.sources=. # 扫描哪个项目的源码,点.表示当前目录
构建测试:这里由于有防止重复构建配置,所以这里选择回退一个版本
构建完毕后,sonarqube的web上就会显示该项目的构建情况
5. 改造项目支持Sonarqube自动扫描
此处改造maven-hello项目
该项目的代码是动态代码,所以配置有些不一样
构建测试
Jenkins通知机制配置(钉钉)
1. 配置钉钉(PC版)
2. jenkins集成钉钉
2.1 安装钉钉的插件
2.2 配置消息通知
2.3 构建测试
Jenkins Pipeline(流水线)
1. 流水线的作用
直观的展示每个阶段做的任务以及每个阶段耗费的时间。
Pipeline使用的语法为Groovy,固定语法。
2. Pipeline语法结构
3. 创建Pipeline
3.1 编写Pipeline
pipeline{
agent any //在哪台主机上运行,这里只有一台,所以写了any
stages { //一个大的任务合集
stage('获取代码') {
steps {
echo "get code ok"
}
}
stage('质量扫描') {
steps {
echo "check code ok"
}
}
stage('编译代码') {
steps {
echo "build code ok"
}
}
stage('部署代码') {
steps {
echo "deploy code ok"
}
}
}
}
3.2 创建Pipeline
3.3 选择执行Pipeline的方式(Pipeline Scripts)
3.4 测试Pipeline
3.5 选择执行Pipeline的方式(Pipeline Script from SCM)
3.6 创建Jenkinsfile
3.7 执行Jenkinsfile
Pipeline项目改造
1. 编辑获取代码语法
2. 编辑质量扫描语法
pipeline{
agent any //在哪台主机上运行,这里只有一台,所以写了any
stages { //一个大的任务合集
stage('获取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '595b3fef-7ed6-49c0-b5f6-cfda454dd6d1', url: 'git@xts.gitlab.com:xts/monitor.git']]])
}
}
stage('质量扫描') {
steps {
sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=html -Dsonar.sources=.
}
}
stage('编译代码') {
steps {
echo "build code ok"
}
}
stage('部署代码') {
steps {
echo "deploy code ok"
}
}
}
}
3. 编辑编译代码语法
pipeline{
agent any //在哪台主机上运行,这里只有一台,所以写了any
stages { //一个大的任务合集
stage('获取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '595b3fef-7ed6-49c0-b5f6-cfda454dd6d1', url: 'git@xts.gitlab.com:xts/monitor.git']]])
}
}
stage('质量扫描') {
steps {
sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=html -Dsonar.sources=.
}
}
stage('编译代码') {
steps {
echo "build code ok" // 这里是静态的代码,所以不用,如果是动态的java代码,则'mvn package'即可
}
}
stage('部署代码') {
steps {
echo "deploy code ok"
}
}
}
}
3. 编辑部署代码语法
pipeline{
agent any //在哪台主机上运行,这里只有一台,所以写了any
stages { //一个大的任务合集
stage('获取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '595b3fef-7ed6-49c0-b5f6-cfda454dd6d1', url: 'git@xts.gitlab.com:xts/monitor.git']]])
}
}
stage('质量扫描') {
steps {
sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=html -Dsonar.sources=.
}
}
stage('编译代码') {
steps {
echo "build code ok" // 这里是静态的代码,所以不用,如果是动态的java代码,则'mvn package'即可
}
}
stage('部署代码') {
steps {
sh 'sh -x /scripts/html_deploy_tag_.sh' //流水线主要是用来做部署的,所以一般不做回退
}
}
}
}
4. 在流水线中添加参数化构建
pipeline{
agent any
parameters { // 参数化构建过程
string(name: 'git_version', defaultValue: 'v1.0', description: '输入tag版本')
}
stages {
stage('获取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '595b3fef-7ed6-49c0-b5f6-cfda454dd6d1', url: 'git@xts.gitlab.com:xts/monitor.git']]])
}
}
stage('质量扫描') {
steps {
sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=$JOB_NAME -Dsonar.sources=.
}
}
stage('编译代码') {
steps {
echo "build code ok"
}
}
stage('部署代码') {
steps {
sh 'sh -x /scripts/html_deploy_tag.sh'
}
}
}
}
5. 在流水线中添加钉钉通知机制
最终如下
pipeline{
agent any
parameters { // 参数化构建过程
string(name: 'git_version', defaultValue: 'v1.0', description: '输入tag版本')
}
stages {
stage('获取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '595b3fef-7ed6-49c0-b5f6-cfda454dd6d1', url: 'git@xts.gitlab.com:xts/monitor.git']]])
}
}
stage('质量扫描') {
steps {
sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=$JOB_NAME -Dsonar.sources=.'
}
}
stage('编译代码') {
steps {
echo "build code ok"
}
}
stage('部署代码') {
steps {
sh 'sh -x /scripts/html_deploy_tag.sh'
}
}
}
post { //钉钉通知,stages所有任务执行后触发post
failure {
dingTalk accessToken: 'bfcc8c10464cd698c30c6390517e1e752a9b30da9aef5e5dc77d887b6e8394c7', imageUrl: '', jenkinsUrl: 'http://xts.jenkins.com:8080', message: '部署失败', notifyPeople: ''
}
success { //构建成功通知
dingTalk accessToken: 'bfcc8c10464cd698c30c6390517e1e752a9b30da9aef5e5dc77d887b6e8394c7', imageUrl: '', jenkinsUrl: 'http://xts.jenkins.com:8080', message: '部署成功', notifyPeople: ''
}
}
}