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代码

v1.1版本

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仓库查看标签是否上传成功
git标签

此处再增加两个标签,分别为v1.2和v1.3,过程同上

4. Jenkins开始构建

4.1 Jenkins构建代码

构建v1.1版本
控制台输出

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)下载插件,然后导入
jenkins官网
搜索插件
选择插件
下载插件
下载插件
导入插件

5.2 配置Git Parameter

删除字符参数功能
添加Git Parameter参数
配置
构建列表

Jenkins通过Tag方式回滚代码

选择历史的发布版本,进行回滚(会导致web机器中有多份不同时间,但相同版本的代码)

回滚前的版本

回滚后的版本

方式2:在脚本中通过软连接方式实现,回滚时,软连接到回滚版本的代码

注意:该方式必须保证web站点目录下,相同的代码版本只有一份,否则回滚就会报错
清理站点目录下,多余的相同版本(后面会介绍,如何防止相同版本代码重复构建)
清理web站点目录
清理web站点目录

重新发布三个版本, 保证每个版本代码,只有一份
web01
web02

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回滚
浏览器验证

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发布新版本代码

v1.4发布
控制台输出
浏览器验证

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安装包

下载tomcat
选择tar包

下载

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

访问tomcat

2. 实现JAVA项目手动上线

2.1 编写java代码

上传准备好的java代码包
java代码包下载点我
提取码:maek
java代码包

[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仓库

gitlab新建项目
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默认的下载源,国外换到国内
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>

更改settings.xml配置文件

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项目
新建java项目
选择mavne类型
源码管理设置
构建前的操作

3.2 jenkins调用maven进行编译(构建)

3.2.1 告诉jenkins,maven安装位置

配置maven路径
配置maven路径
新增maven
新增maven
查看maven安装地址
maven配置完毕

3.2.2 告诉jenkins,jdk的安装位置

新增jdk
新增jdk
查看jdk安装地址

继续配置
保存,再配置
配置maven选项

测试构建
测试构建
测试构建
测试构建

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机器上面软连接的情况

web01
web02

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项目代码

克隆git地址

[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 访问测试

cms网站
登录出错
停掉一台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. 新建任务

新建任务
描述
复制git地址


Git Paramter
添加选项参数

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)数据库配置问题
删除application文件

[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

访问Sonarqube

2.5 登录Sonarqube

用户名密码都是:admin
登录Sonarqube
登录Sonarqube
生成token
生成token

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
SonarQube插件

4.2 告诉Jenkins,Sonarqube服务端安装位置

系统设置
服务端配置

添加token
添加token
保存退出

如果忘记了token,可以如下重新申请:

生成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项目
改造maven-hello项目
配置
该项目的代码是动态代码,所以配置有些不一样
添加sonarqube
保存配置

构建测试
回退版本
跳转到sonarqube

Jenkins通知机制配置(钉钉)

1. 配置钉钉(PC版)

智能群助手
添加机器人
自定义机器人
添加机器人
配置机器人
复制token

2. jenkins集成钉钉

2.1 安装钉钉的插件

插件管理
安装插件

2.2 配置消息通知

选择项目
配置
增加构建后操作
配置构建购操作

2.3 构建测试

构建
构建
消息通知

Jenkins Pipeline(流水线)

1. 流水线的作用

直观的展示每个阶段做的任务以及每个阶段耗费的时间。 
Pipeline使用的语法为Groovy,固定语法。

2. Pipeline语法结构

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

创建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: ''
    }
  }
}
posted @ 2024-01-29 09:34  三花  阅读(431)  评论(0编辑  收藏  举报