SpringCloud实战:Jenkins持续集成

什么是持续集成?

简单来说,大型系统拆分为多个服务后,每个小团队负责一个服务,服务的更新、发布会变得很频繁,通过工具监控代码的每次提交,持续进行自动化的构建过程,就是持续集成。

为什么要用 Jenkins 做持续集成?

Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,是一个免费的开源平台,可以处理任何类型的构建或持续集成。

安装 Jenkins 与其他必备环境
  • 1.服务器环境:centos7(192.168.68.141),Tomcat8 ,Git ,jdk1.8,maven3.5.2
  • 2.Git码云帐号与仓库代码,jenkins从该仓库拉取代码,进行构建编译,构建完后,自动执行shell命令启动服务,完成发布,该仓库下有多个Spring Cloud的服务
    SpringCloud实战:Jenkins持续集成_第1张图片
  • 3.安装 jdk1.8,maven3.5.2,把jdk与maven配置到 /etc/profile中,再 source /etc/profile 使其生效
    SpringCloud实战:Jenkins持续集成_第2张图片
  • 4.centos安装git,yum install git-core,输入 git --version,配置git全局用户与邮箱信息,先把 git 上的项目 clone 到服务器上,看通过 git 命令是否能克隆项目,此步骤很重要,在家目录拉取代码 git clone [email protected]:zhuyu1991/spring-cloud.git 命令的方式拉取到本地,第一次构建时在jenkins中配置该目录,之后的构建,需要配置jenkins的工作区,在 /root/.jenkins/workspace/ 下,下面有说明, 再对jenkins配置定期拉取仓库中的代码进行构建,下面截图说明仓库的代码拉到了本地。
    在这里插入图片描述
    SpringCloud实战:Jenkins持续集成_第3张图片
  • 4.下载 jenkins.war,https://jenkins.io/download/
  • 5.下载 Tomcat ,https://tomcat.apache.org/
  • 6.把 jenkins.war 包放在 tomcat 的 webapps 目录下,启动tomcat
    SpringCloud实战:Jenkins持续集成_第4张图片
  • 7.然后在浏览器中访问 : http://192.168.68.141:8080/jenkins/ , 你将会看到如下界面 , 代表 Jenkins 已经部署完成了,下一步安装配置 Jenkins
  • 获取Jenkins admin的默认密码 cat /root/.ssh/secrets/initalAdminPassword
    SpringCloud实战:Jenkins持续集成_第5张图片
  • 8.进入选择插件安装界面,选择第一个(Install suggested plugins)安装默认Jenkins插件
  • 9.插件安装完成之后,需要创建一个用户
  • 10.进入系统主界面后,点击左侧的系统管理,再点击又侧的管理插件,jenkins需要安装 Git plugin 、Maven Integration插件
  • 11.安装完必备插件后,点击系统管理,再点击全局工具配置,给jenkins 配置 构建需要的 jdk、maven、git,jdk与maven的路径已在 /etc/profile中配置,把路径复制到对应的Home中,git的用默认
    SpringCloud实战:Jenkins持续集成_第6张图片
  • 12.服务器生成ssh key,key分为:id_rsa(私钥),id_rsa.pub(公钥),把公钥配置到git仓库的公钥管理配置处,私钥配置在jenkins中,jenkins凭借私钥向Git仓库拉取代码,Git仓库通过私钥与公钥对比验证决定是否能拉取
  • 在centos中输入:ssh-keygen -t rsa -C “[email protected]”,会在/root/.ssh/下生成2个文件,把公钥配置到git仓库的项目上,把私钥配置到 jenkins 全局凭据中,查看公、私钥:cat /root/.sshh/id_rsa
    SpringCloud实战:Jenkins持续集成_第7张图片
    SpringCloud实战:Jenkins持续集成_第8张图片
  • 13.环境配置工作已经完成,回到主界面,点击新建任务,输入名称,选择构建maven项目,点击保存,如果没有maven说明jenkins的maven插件没有安装
    SpringCloud实战:Jenkins持续集成_第9张图片
  • 14.开始配置 jenkins单个job
    SpringCloud实战:Jenkins持续集成_第10张图片
    选择Git,输入git仓库地址,选择Credentials凭据,就是前面创建的
    SpringCloud实战:Jenkins持续集成_第11张图片
    勾选轮询SCM,每隔10分钟构建一次(H/10 * * * *),只要Git中数据有更新,则触发构建任务
    SpringCloud实战:Jenkins持续集成_第12张图片
    构建环境选择 Add timestamps to the Console Output
    SpringCloud实战:Jenkins持续集成_第13张图片
    注意:Pre Steps Build 需要输入要构建项目的 pom.xml,第一次构建时,因为是在家目录clone的,输入 /root/spring-cloud/fast/pom.xml,第一次构建完后jenkins会把项目拷贝至它的工作目录中 /root/.jenkins/workspace/ 下,第二次构建时需要修改此路径,因为jenkins通过git拉取的代码在此工作目录下

Post Steps 构建完成后添加执行 shell 脚本,脚本的意思是查找eureka-server的进程,并杀死,然后启动 eureka-server包
在这里插入图片描述
SpringCloud实战:Jenkins持续集成_第14张图片

  • 点击保存,再点击构建,左侧会有一个蓝白相间的进度条,点击进度条上面的黑色三角形,查看控制台输出,可以看到 maven 只在编译项目
    SpringCloud实战:Jenkins持续集成_第15张图片
    下面可以看到构建成功了,因设置了构建成功后执行一段脚本,用来启动服务
    所以接下来会执行的shell脚本,内容如下:
#!/bin/bash
echo "********************** Jenkins Stopping SpringBoot Application*************************"
jar_name=eureka-server-0.0.1-SNAPSHOT.jar
pid=`ps -ef | grep $jar_name | grep -v grep | awk '{print $2}'`
if [ -n "$pid" ]
then
#!kill -9 强制终止
   echo "kill -9 的pid:" $pid
   kill -9 $pid
fi
file_path=/root/.jenkins/workspace/eureka-server/eureka/eureka-server/target/
echo "执行....."
java -jar $file_path$jar_name
echo "********************** Jenkins Started SpringBoot Application*************************"

SpringCloud实战:Jenkins持续集成_第16张图片
可以看到日志输出 Started Eureka Server,ok到此构建完成了

访问 eureka-server地址 http://192.168.68.141:10025/ ,可以看到刚刚的构建成功了
SpringCloud实战:Jenkins持续集成_第17张图片
因为上面配置了 轮询 SCM,每隔10分钟查询一次Git仓库,是否有代码提交,有就会触发构建,在Git仓库改动代码后提交(提交时的备注信息是:添加打印日志),等待10分钟的周期,看看是否会构建一次
隔了10多分钟后,进行了一次自动构建,git提交时的备注信息也拉取过来了
SpringCloud实战:Jenkins持续集成_第18张图片

好了,Jenkins轮询拉取 Git 仓库中的代码,有变动就会触发构建,构建后可以执行自定义 shell 脚本,可以很方便的做集成测试,打包到 docker 私有仓库,再通过运维拉取docker镜像到测试、正式环境进行上线
SpringCloud实战:docker部署项目

补充一点,上面是 java -jar xxx.jar 的形式启动,不是后台启动的,jenkins默认会在构建完成后杀掉构建过程中有jenkins中shell命令触发的衍生进程。jenkins根据BUILD_ID识别某个进程是否为构建过程的衍生进程,故修改BUILD_ID后,jenkins就无法识别是否为衍生进程,则此进程能在后台保留运行
1.改造 shell 脚本,能后台启动,在Post Steps中,替换之前的脚本,使用下面的脚本
SpringCloud实战:Jenkins持续集成_第19张图片

OLD_BUILD_ID=$BUILD_ID
echo $OLD_BUILD_ID
BUILD_ID=dontKillMe

#此处放入shell脚本或者shell命令
sh /restartBoot1.sh

BUILD_ID=$OLD_BUILD_ID
echo $BUILD_ID

2.然后在服务器的根目录放一个 restartBoot1.sh 文件,该文件在centos上创建,然后把内容复制进去,因为windows上的文件格式与linux上的不一样,启动时会报错,此处坑了我一下,内容如下:

#!/bin/bash
echo "********************** Jenkins Stopping SpringBoot Application*************************"
pid=`ps -ef | grep eureka-server-0.0.1-SNAPSHOT | grep -v grep | awk '{print $2}'`
if [ -n "$pid" ]
then
#!kill -9 强制终止
   echo "kill -9 的pid:" $pid
   kill -9 $pid
fi
echo "执行....."
nohup java -jar /root/.jenkins/workspace/eureka-server/eureka/eureka-server/target/eureka-server-0.0.1-SNAPSHOT.jar &
echo "********************** Jenkins Started SpringBoot Application*************************"

手动多构建几次,可以看服务器上 eureka-server的进程号,前面的被后面的kill,然后后面的后台启动
SpringCloud实战:Jenkins持续集成_第20张图片

项目中使用了lombok,服务器上 jenkins 编译报错,需要更改maven complier的版本,低版本的才兼容


		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
			
				org.apache.maven.plugins
				maven-compiler-plugin
				3.6.2
				
					1.8
					1.8
				
			
	
			

另外推荐一篇使用docker 安装 jenkins的博客:https://blog.csdn.net/qq_42766492/article/details/90760217,
https://blog.csdn.net/qq_37143673/article/details/97613633
请使用下面语法启动jenkins容器

docker run -d --name jenkins -u root -it --restart=always \
-p 7080:8080 -p 50000:50000 \
-p 8190:8190 \
--privileged=true \
-v /var/jenkins_home:/var/jenkins_home \
-v /home:/home \
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 \
-v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone \
jenkinsci/blueocean
  • -u root:以 root 权限启动,防止出现权限问题
  • -p 7005:8080:端口映射,服务器的 7005 端口映射容器的 8080 端口
  • -p 50000:50000:Jenkins代理默认通过TCP端口50000与Jenkins主机通信
  • -v /data/jenkins:/var/jenkins_home:把容器内的 Jenkins 目录挂载到服务器的 /data/jenkins 目录以防容器没了,数据也没了
  • -v /var/run/docker.sock:/var/run/docker.sock:保证容器内的 docker 与 服务器上 docker 的通讯
  • -v /home:/home 意思是我宿主机上的工作目录映射到容器中,然后就能把文件操作宿主机目录
  • -v /var/jenkins_home,这个很重要,弄了2天才反应过来,在 jenkins 的 Post Steps 执行 Shell 阶段,因为是容器启动的 jenkins,所执行的命令也是在容器中,而不是在宿主机上,所以很容易引起误区
    后面我在宿主机的目录中创建了 deploy.sh脚本, /var/jenkins_home/deploy/deploy.sh,因为映射到了容器,所以容器中也能执行这个脚本,因为把home目录映射到了容器,所以可以通过命令把 打包后的 jar 文件 cp 到 宿主机 /home 目录去
  • -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone 表示容器中的时间与宿主机时间一直,否则编译的java项目部署在容器中后,,new date()得到的时间少了8个小时
OLD_BUILD_ID=$BUILD_ID
echo $OLD_BUILD_ID
BUILD_ID=dontKillMe

#此处放入shell脚本或者shell命令
. /etc/profile
sh /var/jenkins_home/deploy/deploy.sh

BUILD_ID=$OLD_BUILD_ID
echo $BUILD_ID

deploy.sh

#!/usr/bin/env bash
# 输入jenkins环境下的项目路径
export JENKINS_PATH=/var/jenkins_home/workspace/appointment/code/sisco
 
# 输入工作环境上tomcat的全路径
export APP_PATH=/home/test
# 结束原java进程
export pid=`ps -ef | grep appointment-1.0.0.jar | grep -v grep | awk '{print $1}'`
if [ -n "$pid" ]
then
#!kill -9 强制终止
   echo "kill -9 的pid:" $pid
   kill -9 $pid
fi

#echo 'delete appointment-1.0.0.jar file'
rm -f $JENKINS_PATH/appointment-1.0.0.jar

#echo 'cp file '
cp $JENKINS_PATH/target/appointment-1.0.0.jar $JENKINS_PATH/

# 注意这个user.dir,如果你项目中使用到了,请一定要设置
nohup java -DXms400m -DXmx400m -Duser.dir=$JENKINS_PATH/ -jar $JENKINS_PATH/appointment-1.0.0.jar --server.port=8190 --spring.profiles.active=default &

通过端口号,查询进程ID
打印8080端口的进程号:lsof -i:8080 |awk ‘{print $2}’ | tail -n 2
Kill8080端口的进程: kill -9 $(lsof -i:8080 |awk ‘{print $2}’ | tail -n 2)

你可能感兴趣的:(spring,cloud,SpringCloud实战)