目录
传送门
SpringMVC的源码解析(精品)
Spring6的源码解析(精品)
SpringBoot3框架(精品)
MyBatis框架(精品)
MyBatis-Plus
SpringDataJPA
SpringCloudNetflix
SpringCloudAlibaba(精品)
Shiro
SpringSecurity
java的LOG日志框架
Activiti(敬请期待)
JDK8新特性
JDK9新特性
JDK10新特性
JDK11新特性
JDK12新特性
JDK13新特性
JDK14新特性
JDK15新特性
JDK16新特性
JDK17新特性
JDK18新特性
JDK19新特性
JDK20新特性
JDK21新特性
其他技术文章传送门入口
前言
承接 Jenkins的jdk和maven配置一文,
以CentOS7上面的支持JDK8的Jenkins2.346-1的LTS版本和支持JDK17的Jenkins 2.440.1的LTS版本综合介绍Jenkins三种构建类型,默认按照高版本Jenkins2.440.1讲解,有不一样的地方会特别指出低版本Jenkins。
下面文章不定期更新中。。。
Linux安装JDK17(精品)
Linux安装MySQL(精品)
Linux安装Nginx(精品)
Linux安装Maven(精品)
运行一个jar包(精品)
java -jar提示jar中没有主清单属性(no main manifest attribute)(精品)
Jenkins安装启动(JDK8/11/17)(精品)
Jenkins配置(插件/角色/凭证)(精品)
Jenkins的jdk和maven配置(精品)
Jenkins三种构建类型(精品)
一、概念
Jenkins中自动构建项目说白了,就是让java项目自动更新代码,自动打包,自动kill之前的java项目,自动发版新打包的java项目。可以配置纯Linux操作,也可以配置Docker方式的。
Jenkins中自动构建项目的类型有很多,常用的有以下三种:
自由风格软件项目(FreeStyle Project)
Maven项目(Maven Project)
流水线项目(Pipeline Project)
默认只有第一个自由风格软件项目,我们主要用的也是这个,其他的需要Maven等插件支持。
点击New Items
默认就是第一个自由风格软件项目(FreeStyle Project)。笔者接下来主要讲解常用的三种。
二、前置处理(必做)
1、赋予777权限
在依赖脚本处理的时候,需要放权。
# 不可以偷懒直接给var文件夹赋权,会导致很多错误。有些文件夹不能有太高的权限。
chmod 777 -R /var/lib/jenkins
chmod 777 -R /var/cache/jenkins
chmod 777 -R /var/log/jenkins
2、让jenkins用户拥有root用户的kill权限
# gpasswd -a jenkins root # jenkins用户加入到root组,这个命令可以先不管,如果一直报错,可尝试
sudo visudo # 修改sudoers文件,在最后一行加入下面内容
jenkins ALL=(ALL) NOPASSWD: /bin/kill # 让jenkins拥有root的kill权限
sudo -k # 该命令来清除sudo缓存
注意:重启jenkins!!!
3、要运行jar包端口号需要大于1024
比如笔者的feBackEnd-1.jar,里面的端口号是81,实际操作,由于jenkins用户操作的,java -jar权限不够,会导致启动报错,所以读者jar包的端口号最好是改成大于1024的。另一种就是不用jenkins用户操作,将jenkins配置文件里面的jenkins用户和jenkins组都改成root。见下面文章的五、常见报错分析-kill没有权限,有相关操作教程。
三、自由风格软件项目(FreeStyle Project)(推荐)
输入我们的软件项目名称,这个可以随便自定义名称,但是多个微服务的时候,建议还是用微服务名称,这样很多个的时候,很好区分。
例如笔者后端项目叫feBackEnd,打包为feBackEnd-1.jar,在Jenkins这边就写入feBackEnd。
输入项目名称后点击FreeStyle Project,然后再点击ok。
注意:长时间不操作Jenkins,会超时的,会导致一些报错。这个时候重新登录一下Jenkins就好了。
笔者这边默认都设置为3个,强烈建议设置好。后面文章会单独提到这块为什么要设置这些。
Source Code Management这块,如果没有看到Git和Subversion,则是需要重新去装插件(就是Git和Subversion两个单词,不扩展不省略),然后重启。插件安装可以参考笔者之前的文章,Jenkins配置(插件/角色/凭证)
输入地址提示错误,是笔者Jenkins所在的Linux服务器没有安装Git导致的,SVN报错同理。
笔者服务器为CentOS,用下面指令安装git,如果是svn则把git单词换成subversion即可。用svn --version检查。
sudo yum install git # 一路y就可以了
git --version # 检查git
git ls-remote -h https://gitee.com/zangtie/feproject.git # 显示远程仓库https://gitee.com/zangtie/feproject.git中的引用列表,通常我们说的Head,也就是最新提交的版本。如果显示了像我下面截图9f5b.....a91ac之类的字符串,那说明Jenkins所在服务器的git配置OK了。
如果是下图这种提示,那么配置的账户和密码肯定是不对的。查看zangtie的git账户密码。
下面这个指令,马上就可以验证密码。
git ls-remote -h https://gitee.com/zangtie/feproject.git # 显示远程仓库https://gitee.com/zangtie/feproject.git中的引用列表,通常我们说的Head,也就是最新提交的版本。如果显示了像我下面截图9f5b.....a91ac之类的字符串,那说明Jenkins所在服务器的git配置OK了。
然后我们重新登录Jenkins看下配置,注意,还是不行的话,可以重启jenkins查看。
点击刚刚没有配置完成的feBackEnd
点击左侧的Configure,后面反复配置一个项目,都是从这里点进来。
这下红字提示没有了。
接下来是最重要的一步
Build Steps这步选择Execute shell,我们通过执行脚本来更新jar包,打包jar包,kill 旧的jar进程id,发版新的jar包。
先看一个纯净版shell
fileName=feBackEnd-1.jar
pathName=feBackEnd
logFile=fe.txt
cd ./$pathName
echo "开始编译和打包"
mvn clean package -Dmaven.test.skip=true
echo "编译和打包结束"
PID=$(ps -ef | grep $fileName | grep -v grep | awk '{ print $2 }')
if [ ${PID} ];
then
echo 'Application is stoping...'
echo kill $PID DONE
sudo kill -9 $PID
else
echo 'Application is already stopped...'
fi
mv /var/lib/jenkins/workspace/$pathName/$pathName/target/$fileName /java/$fileName
cd /java
BUILD_ID=dontKillMe nohup java -Xms512m -Xmx512m -jar $fileName > $logFile 2>&1 &
echo "启动项目"
if [[ ! -f $logFile ]]; then
sleep 2
fi
sleep 20
tail -n 20 $logFile
aaa=`grep "Started" $logFile | awk '{print $10}'`
if [[ -n "${aaa}" ]];then
echo "启动成功"
exit 0
else
echo "启动失败"
exit 1
fi
下面解释一下这个sheel的大概意思(强烈建议认真看一下,脚本是重中之重,后面报错的排错也基本在脚本这边)
fileName=feBackEnd-1.jar # 定义一个变量fileName
pathName=feBackEnd # 定义一个变量pathName
logFile=fe.txt # 定义一个变量logFile
cd ./$pathName # Jenkins执行脚本的默认工作目录会在控制台打印输出,笔者这儿测试的时候是/var/lib/jenkins/workspace/feBackEnd,注意这里面有大坑。后面文章会具体说明。
echo "开始编译和打包" # 这个是在jenkins控制台打印输出的,给我们自己看的,看进行到哪一步了
mvn clean package -Dmaven.test.skip=true # 我们打包发版,基本是先clean旧的calss文件,然后重新打包jar包或者war包。如果是聚合模块,mvn clean package -Dmaven.test.skip=true -pl economic-auth-server/auth-server -am;其中economic-auth-serve是总模块,auth-server 是子模块,这样就可以只clean package 子模块。笔者后面文章Maven项目的案例就是聚合模块的。
echo "编译和打包结束" # 控制台输出
PID=$(ps -ef | grep $fileName | grep -v grep | awk '{ print $2 }') # 找到feBackEnd.jar对应的进程id
if [ ${PID} ]; # 如果存在进程id。
then
echo 'Application is stoping...'# 控制台输出,应用程序正在被停止
echo kill $PID DONE # 控制台输出kill 进程id 字样
sudo kill -9 $PID # kill杀掉进程,结束之前运行的jar或者war包进程
else # 不存在进程id,说明之前jar包已经被结束了
echo 'Application is already stopped...'# 控制台输出,应用程序已经停止
fi
mv /var/lib/jenkins/workspace/$pathName/$pathName/target/$fileName /java/$fileName #这个是将新打的包移动到自己Linux服务器的一个工作目录下。前面路径是jenkins帮你打包的工作目录,后面目录是我自己在Linux新建的一个目录,就是想看到jenkins工作没有。熟悉打包的读者,可以忽略这步,直接就在jenkins的工作目录搞。
# 特别注意1:很多读者没有成功,就是这边的路径配置错误了,因为Jenkins版本不同,所以jenkins帮你打包的工作目录也不同。一定要到自己服务器的工作目录看看,真实路径是怎么样的。比如笔者这个高版本Jenkins的工作目录是这样的:/var/lib/jenkins/workspace/feBackEnd/feBackEnd ,所以上面指令就对应的配置即可。
# 特别注意2:之前的前置处理一定要做好。否则会有很多访问权限问题。
cd /java # 进入我在Linux新建的那个目录里面,如果是Jenkins工作目录直接搞,这里就是 cd /var/lib/jenkins/workspace/feBackEnd/feBackEnd
BUILD_ID=dontKillMe nohup java -Xms512m -Xmx512m -jar $fileName > $logFile 2>&1 & # 发版指令,堆内存大小读者根据自己需要调整大小
echo "启动项目" # 控制台输出
if [[ ! -f $logFile ]]; then # 这步其实可以忽略。就是没有日志文件的时候,给了一个创建日志文件的时间
sleep 2 # 2秒
fi
sleep 20 # 这个时间可以根据项目启动的时间灵活调整,我jar包启动很快,所以20秒足够了,如果Linux的respository仓库还没有任何jar包,那么这个时间根据读者jar包的体量,第一次还是弄特别大些,等Linux的respository仓库该有的jar包都有了以后,再把时间改小。笔者建议还是拷贝本地win电脑的respository仓库到Linux上最好。
tail -n 20 $logFile # 这个是为了查看启动的时候打印日志,查看是否启动成功,启动报错的信息显示出来
aaa=`grep "Started" $logFile | awk '{print $10}'` # 指令的解释:|前面为 在整个日志文件里面去找 Started这个单词,如果找到了,就print这个单词出来,print $10就是打印10个字符长度。aaa=就是给赋值了。实际就是 aaa=Started了。如果没有找到,aaa=“”了。这个是抓捕了jar包启动成功的一个标志,比如springboot启动成功后,里面日志里面包含了 Started这个单词,读者也可以根据自己的转有单词抓捕。
if [[ -n "${aaa}" ]];then # aaa不为空串的时候
echo "启动成功" # 输出启动成功
exit 0 # 退出并返回0
else
echo "启动失败" # 输出失败
exit 1 # 退出并返回1
fi
配置脚本后点击保存,整个配置完成。
接下来就是激动人心的时刻了,点击Build Now
然后点击左下角的进度条
在这边的Console Output可以看到打印出的一些东西。像我们idea本地开发一样,一览无余。顺利的话,启动完成。自动化发版就构建完成了。
三、Maven项目(Maven Project)
这边以聚合项目,并且是笔者汉化包的对应jdk8的低版本Jenkins讲解。如果自由风格软件项目很熟悉了,这边操作起来就很简单了。
首先 安装Maven Integration插件,安装失败就看下插件那边教程。
安装插件重启Jenkins以后,可以看到多了maven项目的选择。我们选择maven项目。
这个是笔者的一个聚合项目,根pom.xml下面有很多子模块
clean install -Dmaven.test.skip=true -pl economic-auth-server/auth-server -am
这条指令就是解决聚合模块最关键的指令。其他类似自由风格软件项目,增加脚本就可以了。
纯净版脚本,读者可以根据自己真实情况,修改下面的变量,以及注意工作目录这些基本信息的脚本修改。
fileName=auth-server-0.0.1-SNAPSHOT.jar
pathName=economic-auth-server/economic-auth-server/auth-server
logFile=auth-server.txt
PID=$(ps -ef | grep $fileName | grep -v grep | awk '{ print $2 }')
if [ ${PID} ];
then
echo 'Application is stoping...'
echo kill $PID DONE
kill -9 $PID
else
echo 'Application is already stopped...'
fi
mv /var/lib/jenkins/workspace/$pathName/target/$fileName /java/$fileName
cd /java
BUILD_ID=dontKillMe nohup java -Xms512m -Xmx512m -jar $fileName > $logFile 2>&1 &
echo "启动项目"
if [[ ! -f $logFile ]]; then
sleep 2
fi
sleep 20
tail -n 20 $logFile
aaa=`grep "Started" $logFile | awk '{print $10}'`
if [[ -n "${aaa}" ]];then
echo "启动成功"
exit 0
else
echo "启动失败"
exit 1
fi
四、流水线项目(Pipeline Project)
流水线项目,笔者这边参考了黑马程序员的一些方案
1、概念
比其他的类型多了一个流水线,点击流水线语法
2、拉取代码
拉取代码
点击这个按钮,就生成了代码,把这个代码拷贝到前面截图中的流水线中。
拷贝
这个才是正确截图,其他截图少个 agent any。
3、编译打包
编译打包,用的脚本命令
将生成的代码拷贝过来
4、项目部署
项目部署
将生成的代码拷贝过去
拷贝
5、Jenkinsfile文件
项目跟目录下穿件Jenkinsfile文件,在流水线定义这边选择截图的,可以直接读取到这个文件的配置。这个文件配置就是把上面的3步代码放进去,这样做是为了让git等工具管理起Jenkins代码的迭代。
五、常见报错分析
1、路径错误
错误如下:
下面截图是默认工作目录
下面截图是可以看到pom.xml也就是src文件夹所在目录
可以看到笔者这边默认工作路径是/var/lib/jenkins/workspace/feBackEnd,而实际上,还得加一层目录才能看到pom.xml,因为我们打包都是依赖Maven,而Maven则主要靠项目中的pom.xml去工作,所以真正的干活儿目录应该 /var/lib/jenkins/workspace/feBackEnd/feBackEnd
如果读者在/var/lib/jenkins/workspace/feBackEnd下面就可以看到pom.xml了,那么就不能像笔者那样再进入一层,反正就是以pom.xml所在的目录去clean package才对。
2、kill没有权限
脚本里面执行kill操作的时候,提示没有权限。
ps -ef |grep java
可以发现jenkins启动的时候并不是root用户,而是jenkins用户。笔者尝试脚本里面的kill -9 前面加个sudo ,变成 sudo kill -9 ,这种也不行的,会有新的错误,不过sudo一定要加上。
这种时候有三个思路。
思路一:脚本里面增加su 去切换到root用户,但是需要输入root密码,这样脚本里面有暴露root用户密码的风险,不太推荐。
思路二(推荐):修改jenkins权限,让jenkins用户执行kill命令时候有root权限
sudo visudo # 修改sudoers文件,在最后一行加入下面内容
jenkins ALL=(ALL) NOPASSWD: /bin/kill # 让jenkins拥有root的kill权限
# jenkins ALL=(ALL:ALL) ALL # 让jenkins拥有root的所有权限(推荐,可以一劳永逸解决很多问题)
sudo -k # 该命令来清除sudo缓存
然后建议重启jenkins,重新Build Now。注意sheel脚本是 sudo kill -9 $PID,是包含sudo单词的。不然也会报错。
思路三:直接将Jenkins的配置文件中的用户和组对应的值jenkins修改为root。这种是最简单的办法,直接用root启动Jenkins,所有权限问题都不存在了。但是企业级开发中,很多时候是禁用root账户的。所以笔者才推荐思路二。其实思路三可以一劳永逸的解决很多潜在问题。
# 直接换成root
vim /etc/sysconfig/jenkins # 如果有就修改,比如低版本Jenkins会有
vim /etc/init.d/jenkins # 如果有就修改
vim /usr/lib/systemd/system/jenkins.service # 将User和Group都修改为root
systemctl daemon-reload
chown -R root:root /var/lib/jenkins # 原来是jenkins用户启动的,这些文件权限属于jenkins组jenkins用户,现在修改为root组root用户。
chown -R root:root /var/cache/jenkins # 同上
chown -R root:root /var/log/jenkins # 同上
注意:重启jenkins!!!重新Build Now,可以发现问题解决了。
3、项目启动报错
在编译报错、kill报错都解决以后,发现好好的项目,启动居然报错了。这个时候,最简单的方式就是,先不用Jenkins,直接java -jar feBackEnd.jar,先看下直接启动,能否启动成功。有些时候,一些中间件没有启动起来,会导致jar包启动失败,比如redis、MySQL等等。笔者这边遇到个很坑的东西,就是笔者的Linux服务器运行了太多东西,导致笔者内存不够用了,也会导致jar包启动不了,这种时候就得kill些其他程序了。
在直接java -jar feBackEnd.jar启动不报错以后,内存够用以后,我们再来细看Jenkins报错的问题。
首先还是权限问题,比如如果是阿里云服务器,开启了,阿里云很多的权限规则或者防病毒监控的一些功能,会导致jenkins用户的权限不够,出一些莫名其妙的问题。
sudo chmod 777 -R /java
会发现,修改/java的指令不被容许了。我们来看下ChatGPT的回答,接下来跟着ChatGPT给的思路来解决。笔者这边将81端口改成了8081,一下子就好了,读者可以根据实际情况,最好一个一个都过一下。最后第5条,就是笔者指出的阿里云的防病毒之类的一些东西,可以关闭试一下。如果是华为云、青云、腾讯云等,也是类似的操作。如果是企业级的则慎重关闭。
六、jenkins清除构建历史防止磁盘爆满(非常重要)
笔者的自由风格软件项目高版本案例已经处理了。但是这边还是单独提一下,这边案例是低版本Jenkins案例。
/var/log/jenkins/jenkins.log 这个jenkins的日志,一般不会太大,删除需要先关闭jenkins的进程,然后再物理删除。这个不是本篇重点。
/var/lib/jenkins/jobs 在这个jobs下面会发现我们大量的构建项目,占用大量空间,在我们给项目配置的地方,勾选上 丢弃旧的构建,把高级也设置上,本次设置3。
设置丢弃旧的构建前,这边文件非常多,构建一次一个文件夹,非常占用硬盘
设置以后,发版一次,会自动删除多余的构建,very nice
七、jenkins的另一种日志磁盘爆满(非常重要)
/var/lib/jenkins/logs 文件夹下面的一种日志,主要是csp里面的日志,我直接手动删除了这个文件夹,没什么问题。硬盘直接释放出70%的硬盘空间。
后面是网上找到的一种功能,是否有效待验证。在/etc/logrotate.d/jenkins或/etc/logrotate.d/jenkins-oc中找到
设置为每天轮换并仅保留一周(轮换为7),或者根据maxsize或组合设置特定的限制.
/var/log/jenkins/jenkins.log /var/log/jenkins/access_log {
weekly
copytruncate
missingok
rotate 52
compress
delaycompress
notifempty
}
八、jenkins重启项目全部丢失
笔者之前搞前端项目放进jenkins 的时候,发生了一次事故,这里记录一下
原因:更新前端node.js插件后重启导致所有项目丢失,但是前端项目还在。网上查找发现
vim /etc/profile
export JENKINS_HOME=/var/lib/jenkins
这些都是配置好的,根本不是这个问题。由于提前在百度网盘备份了插件,将更新后的两个插件还原,重启以后解决了。后面就把全部jenkins插件都备份了,太吓人了。
总结:大家最好是把jenkins插件都备份,尤其是低版本的对应JDK8的Jenkins,有时候操作设置的时候,真的很容易出问题。到此Jenkins的讲解完成了,祝大家用Jenkins用的愉快。