Jenkins是目前最流行的开源CI(持续集成)工具,广泛用于项目开发,部署和自动化等。
本文将带着大家一起完成在阿里云Centos 7服务器间完成Jenkins+Maven
自动化部署SpringBoot压测环境整个过程。
该方案使用Jenkins把打包后的Jar包通过SSH免密的方式上传到测试应用服务器指定目录,上传成功后执行服务器的shell脚本,该脚本会备份原有程序并kill原有程序进程,部署完Jar并再次启动,执行的结果的自动化在钉钉群里通知。
在搭建之前,你必须满足:
检查服务器是否安装了OpenJDK
[zzw@7dgroup3 usr]$ yum list installed |grep java
java-1.8.0-openjdk.x86_64 1:1.8.0.181-3.b13.el7_5 @updates
java-1.8.0-openjdk-headless.x86_64 1:1.8.0.181-3.b13.el7_5 @updates
javapackages-tools.noarch 3.4.1-11.el7 @base
python-javapackages.noarch 3.4.1-11.el7 @base
tzdata-java.noarch 2018e-3.el7 @updates
卸载OpenJDK
[zzw@7dgroup3 usr]$ sudo yum -y remove java-1.8.0-openjdk.x86_64
[zzw@7dgroup3 usr]$ sudo yum -y remove java-1.8.0-openjdk-headless.x86_64
把预先下载的jdk-8u191-linux-x64.tar.gz包上传到服务器并解压
[zzw@7dgroup3 ~]$ tar -zxvf jdk-8u191-linux-x64.tar.gz
移动jdk1.8.0_191文件夹到/usr/local/java/
目录下
sudo mv jdk1.8.0_191/ /usr/local/java/
配置JDK环境变量
#备份配置文件
[zzw@7dgroup3 jdk1.8.0_191]$ sudo cp /etc/profile /etc/profilebackup
[zzw@7dgroup3 jdk1.8.0_191]$ sudo vim /etc/profile
#使配置文件立即生效
[zzw@7dgroup3 jdk1.8.0_191]$ sudo source /etc/profile
JDK环境变量
#set java environment
export JAVA_HOME=/usr/local/java/jdk1.8.0_191
export PATH=$JAVA_HOME/bin:$PATH
检查JDK环境
[zzw@7dgroup3 jdk1.8.0_191]$ java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
下载软件
[zzw@7dgroup3 ~]$ wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz
解压软件并移动到指定目录
[zzw@7dgroup3 ~]$ tar zvxf apache-maven-3.5.4-bin.tar.gz
[zzw@7dgroup3 ~]$ sudo mv apache-maven-3.5.4 /usr/local/maven
配置环境变量
[zzw@7dgroup3 ~]$ sudo vim /etc/profile
[zzw@7dgroup3 ~]$ source /etc/profile
环境变量
#set maven environment
MAVEN_HOME=/usr/local/maven
export MAVEN_HOME
export PATH=${PATH}:${MAVEN_HOME}/bin
由于maven默认配置的仓库在国外导致下载速度较慢,所以我们最好为配置一个国内的镜像,这里为maven配置阿里云仓库
[zzw@7dgroup3 ~]$ cd /usr/local/maven/conf/
找到settings.xml
在mirrors节点下添加:
<mirrors>
<mirror>
<id>alimavenid>
<mirrorOf>centralmirrorOf>
<name>aliyun mavenname>
<url>http://maven.aliyun.com/nexus/content/repositories/central/url>
mirror>
mirrors>
检查maven环境
[zzw@7dgroup3 ~]$ mvn -version
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
Maven home: /usr/local/maven
Java version: 1.8.0_191, vendor: Oracle Corporation, runtime: /usr/local/java/jdk1.8.0_191/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-862.9.1.el7.x86_64", arch: "amd64", family: "unix"
下载软件
[zzw@7dgroup3 ~]$ wget https://pkg.jenkins.io/redhat-stable/jenkins-2.138.2-1.1.noarch.rpm
安装软件
[zzw@7dgroup3 ~]$ sudo yum localinstall jenkins-2.138.2-1.1.noarch.rpm
启动Jenkins服务并将其设置为在引导时运行
[zzw@7dgroup3 ~]$ sudo systemctl start jenkins.service
[zzw@7dgroup3 ~]$ sudo systemctl enable jenkins.service
Jenkins启动成功,它自带Jetty服务器
通过http://
访问
第一次启动Jenkins时,出于安全的考虑,Jenkins会自动生成一个随机的口令。在服务器上使用root账号登录获取口令复制下来再浏览器内输入口令。
[zzw@7dgroup3 jenkins]$ su - root
[root@7dgroup3 ~]# cd /var/lib/jenkins/secrets/
[root@7dgroup3 secrets]# cat initialAdminPassword
0d3127496a1f4ee3a326ebfa21a8ddc6
管理员密码输入0d3127496a1f4ee3a326ebfa21a8ddc6
进入用户自定义插件界面,建议选择安装官方推荐插件。
进入插件安装进度界面
配置用户密码
实例配置
安装完成
有很多插件默认就已经安装了,需要我们安装的并不多。
需要安装插件如下:
从系统管理>插件管理>可选插件>搜索插件>勾选安装,点击直接安装即可
系统管理>全局工具配置
配置本地maven路径,去掉勾选自动安装
其他内容可根据自己的情况选择安装配置。
ssh的配置可使用密钥,也可以使用密码,这里我们使用密钥来配置。
首先检查服务器上是否已经生成密钥,如果没有使用ssh-keygen -t rsa
生成密钥
[root@7dgroup3 ~]# cd ~/.ssh/
[root@7dgroup3 .ssh]# ls
authorized_keys known_hosts
[root@7dgroup3 .ssh]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:pJPHl58jAM/a3eaCfCTQxOAIGomm3WSTYwWBlTKrs5E root@7dgroup3
The key's randomart image is:
+---[RSA 2048]----+
|o..o+*oo |
|o++.Oo o |
|+. O.ooo. |
|. o . .O. . |
| o +.S o |
|E =.+.o . |
| + ...+o * |
|. o o+ . |
| . .. |
+----[SHA256]-----+
[root@7dgroup3 .ssh]# ls
authorized_keys id_rsa id_rsa.pub known_hosts
注意:一个矩形图形出现就说明成功,在~/.ssh/
下会有私钥id_rsa
和公钥id_rsa.pub
将Jenkins服务器的公钥id_rsa.pub
中的内容复制到测试应用服务器~/.ssh/
下的authorized_keys
文件中
[root@7dgroup3 .ssh]# ssh-copy-id -i id_rsa.pub 47.92.172.x
测试应用服务器授权并重启SSH服务
#公钥文件授权
[root@zuozewei .ssh]# chmod 644 ~/.ssh/authorized_keys
[root@zuozewei .ssh]# service sshd restart
Redirecting to /bin/systemctl restart sshd.service
在Jenkins服务器使用ssh IP测试免密是否能够登录
[root@7dgroup3 .ssh]# ssh 47.92.172.x
Last login: Wed Oct 24 20:34:29 2018 from 111.201.79.x
Welcome to Alibaba Cloud Elastic Compute Service !
注意:这里最好使用root用户密钥进行认证
接下来就是配置Jenkins了
系统管理>系统设置>选择Publish Over SSH
公共配置:
Passphrase:不用设置
Path to key:key文件(私钥)的路径
Key:将私钥复制到这个框中
Hostname:需要连接ssh的主机名或ip地址(建议ip)
Username:用户名
Remote Directory:远程目录,不用设置
Name:随意起名代表这个服务,待会要根据它来选择
高级配置:
Disable exec:禁止运行命令,这个不要勾选,否则没法执行命令
Use password authentication, or use a different key:可以替换公共配置(选中展开的就是公共配置的东西,这样做扩展性很好)
Port:端口(默认22)
Timeout (ms):超时时间(毫秒)默认即可
配置完成后Test Configuration
下,提示success的话就没问题。
首页>新建>输入一个任务名称>构建一个maven项目
勾选丢弃旧的构建,选择是否备份替换的旧包。
源码管理选择Git,使用Https方式拉取源代码,注意如果拉取其它分支版本,请在Branch Specifier
输入分支名称
构建触发器中选择轮训SCM,设置每天7点左右定轮询Git
定时构建:无论Git中数据有无变化,均执行定时化的构建任务
轮训SCM:定时轮询Git,查看Git中是否有数据变化,如果有变化,则执行构建任务
定时构建语法:
* * * * *
下面为举例:
H/10 * * * *
或*/10 * * * *
0 8 * * *
0 8-17/2 * * *
0 8-17/2 * * 1-5
H H 1,30 1-6 *
构建环境中勾选Add timestamps to the Console Output
,构建的过程中会将日志打印出来
在Build中输入打包前的mvn命令:clean install -Dmaven.test.skip=true
-Dmaven.test.skip=true
表示跳过单元测试
Post Steps 选择Run only if build succeeds
点击Add post-build step
,选择 Send files or execute commands over SSH
,Name选择上面配置的Push SSH
arget/person-0.0.1-SNAPSHOT.jar
项目jar包名target/
Jenkins-in/
应用服务器的发送目录地址Jenkins-in/build.sh
应用服务器对应的shell脚本构建后操作,点击添加“钉钉通知器”
钉钉access token在钉钉群的机器人配置内获取
测试应用服务器创建/root/jenkins-in
目录
[root@zuozewei ~]# pwd
/root
[root@zuozewei ~]# mkdir jenkins-in
测试应用服务器创建Jenkins-in目录下创建build.sh脚本
#格式化时间
DATE=$(date +%Y%m%d)
#设置程序目录
DIR=/usr/local/app
#设置Jar名称
JARFILE=person-0.0.1-SNAPSHOT.jar
#判断是否存在backp目录,如果不存储就创建
if [ ! -d $DIR/backup ];then
mkdir -p $DIR/backup
fi
cd $DIR
#杀掉当前运行的旧程序
ps -ef | grep $JARFILE | grep -v grep | awk '{print $2}' | xargs kill -9
#备份旧程序
mv $JARFILE $DIR/backup/$JARFILE$DATE
#部署新程序
mv -f /root/jenkins-in/$JARFILE .
echo "The service will be starting"
#后台启动程序并设置Jvm参数、开启JMX、打印GC日志
java -server -Xms1024M -Xmx1024M -XX:PermSize=256M \
-XX:MaxPermSize=256M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails \
-Xloggc:./gc.log \
-Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=127.0.0.1 \
-Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-jar $JARFILE --spring.profiles.active=dev > /nohup 2>&1>out.log &
if [ $? = 0 ];then
sleep 30
tail -n 50 out.log
fi
cd backup/
ls -lt|awk 'NR>5{print $NF}'|xargs rm -rf
echo "starting success!!!"
~
~
这段shell脚本的大体意思就是,kill旧程序>删除旧程序>启动新程序>备份旧程序
点击“立即构建”,任务控制台将实时输出相关信息
看到输出了starting success!!!,说明我们的需要测试的程序已经跑起来了。
我们可以去测试应用服务器上验证下
[root@zuozewei app]# ps -ef|grep person
root 16901 15477 0 21:06 pts/1 00:00:00 grep --color=auto person
root 31218 1 0 17:48 ? 00:00:29 java -server -Xms1024M -Xmx1024M -XX:PermSize=256M -XX:MaxPermSize=256M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -Xloggc:./gc.log -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar person-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
[root@zuozewei app]# ls
backup gc.log out.log person-0.0.1-SNAPSHOT.jar
[root@zuozewei app]# cd backup/
我们看到已经成功设置JVM参数,生成了gc.log、out.log。
我们看到需要测试程序已经成功运行了,但是还需要验证一下是否功能正常?
我们通过验证此程序其中的查询人员接口
/**
* 查询一个人员
* @param id
* @return
*/
@GetMapping(value = "/person/{id}")
public Person personFindOne(@PathVariable("id") Integer id) {
return personRepository.findOne(id);
}
这个接口比较简单,只需要我们向指定的URL请求一个人员ID即可,这里我们使用Postman验证这个接口
我们看到接口正确返回数据了,说明自动部署的程序没有问题。
下面我们把这个查询人员的接口的URL修改并重新提交到git上
/**
* 查询一个人员
* @param id
* @return
*/
@GetMapping(value = "/person/find/{id}")
public Person personFindOne(@PathVariable("id") Integer id) {
return personRepository.findOne(id);
}
重新构建项目,完成后我们可以在Jenkins上看到代码更新记录
接下来我们验证下新更新程序是否部署成功,我们还是使用Postman请求新修改的接口地址
我们看到新的接口的地址已经成功发布了,接下来我们查看下测试应用服务器情况
[root@zuozewei backup]# ps -ef|grep person
root 18659 1 6 21:25 ? 00:00:17 java -server -Xms1024M -Xmx1024M -XX:PermSize=256M -XX:MaxPermSize=256M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -Xloggc:./gc.log -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar person-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
root 19113 15477 0 21:30 pts/1 00:00:00 grep --color=auto person
[root@zuozewei backup]# ls
person-0.0.1-SNAPSHOT.jar20181025
[root@zuozewei backup]# cd ..
[root@zuozewei app]# ls
backup gc.log out.log person-0.0.1-SNAPSHOT.jar
我们看到旧的程序已经成功备份,至此我们的自动化部署SpringBoot压测环境已经大功告成!