错误记录:解决Jenkins运行nohup命令启动Java无效问题
1. 问题重述:
通过jenkins执行shell脚本时,脚本中是通过nohup java -jar &的方式启动,显示执行成功,但是服务却没启动,脚本如下:
#!/bin/bash
pid=$(pgrep -f school-boot.jar)
if [ -n "$pid" ]; then
kill -9 "$pid"
echo "停止 school-boot.jar 进程成功(PID $pid)"
fi
nohup java -jar /usr/local/examsystem/back/school-boot.jar --spring.profiles.active=prod >msg.log 2>&1 &
echo "重新启动成功"
脚本本身没有问题,直接在Linux终端可以正常kill和正常启动。但是在Jenkins自动部署执行脚本的时候,只有kill有效,无法正常启动。
2. 问题排查
- 因为端口关闭成功,首先排除文件位置、用户权限、文件权限等常见问题。
- 输出nohup文件,但是文件为空。可以判断已执行启动命令,但是启动失败。
- 顺着2的思路直接放入nohup命令代替sh命令,执行启动发现失败。大概确定是nohup命令有问题。
3. 结论
jenkins默认会在构建完成后,杀掉构建过程中由shell命令触发的衍生进程。
jenkins根据BUILD_ID识别某个进程是否为构建过程的衍生进程,故修改BUILD_ID后,jenkins就无法识别是否为衍生进程,则此进程能在后台保留运行。
简单来说就是nohup命令运行需要保持会话支持,因为我们直接连上Linux终端的时候,该会话是一直存在的,所以能够执行成功。但是jenkins在执行完一条shell命令之后就会断开会话,因此,只会运行一下nohup,随后马上关闭会话,导致nohup并没有成功,也就无法正常启动后续的java服务。
4. 解决
- 使用 BUILD_ID=xxx ,其中xxx可以是任意内容(只要不是原来的BUILD_ID内容即可),同时需要把nohup输出内容重定向到文件里面,如
/usr/local/msg.log
#!/bin/bash
export BUILD_ID=dontKillMe
pid=$(pgrep -f school-boot.jar)
if [ -n "$pid" ]; then
kill -9 "$pid"
echo "停止 school-boot.jar 进程成功(PID $pid)"
fi
nohup java -jar /usr/local/examsystem/back/school-boot.jar --spring.profiles.active=prod >msg.log 2>&1 &
echo "重新启动成功"
- 不适用nohup命令启动进程,使用at now代替。
#! /bin/bash
#so "at now" will run even if java -jar fails
set +e
#Run java app in background
echo "java -jar /usr/local/examsystem/back/school-live.jar" | at now
评论区