jenkins构建成功但无法启动进程

momo314相同方式共享非商业用途署名转载

最近用jinkens的时候遇到一个场景,是这样的:

因为服务器资源有限,jenkins和需要构建发布的web应用程序只能放在同一台服务器上。编译成功之后会调用一个脚本将编译好的jar包拷贝到指定的目录,然后调用另一个脚本,杀死原有进程并重新启动新进程,脚本会检测应用程序启动时输出的日志,发现启动成功之后返回构建成功。

这时候会产生一个问题:jenkins构建成功,脚本也检测到应用程序启动成功,然而使用netstat查看端口占用情况的时候发现对应的端口并没有被占用,也就是说,应用程序并没有启动成功。

下面是排查问题的过程,废话略多,不关心的直接看最后

最开始是怀疑自己的脚本写的有问题,然而直接执行脚本又确实能正常启动引用程序,那应该是排除了脚本问题了。

又经过一番解决问题全靠猜之后,开始怀疑是不是jenkins账号权限的问题。因为毕竟是部署到本机,也就意味着这个脚本是由jenkins账号来执行的,那么会不会是jinkins账号权限问题导致进程被干掉呢?

呵呵,各种尝试,也不是。。。

不过,这个猜测其实也已经沾边了,因为最后翻文档找到了这么一段话:

To reliably kill processes spawned by a job during a build, Jenkins contains a bit of native code to list up such processes and kill them. This is tested on several platforms and architectures, but if you find a show-stopper problem because of this, you can disable this feature by setting a Java property named "hudson.util.ProcessTree.disable" to the value "true".

Jenkins - ProcessTreeKiller

大致意思呢,就是说:jenkins自身有一个机制,这个机制能够监测到所有在构建过程中由作业产生的进程,然后在构建完成之后杀死这些进程。

这就是为什么使用jenkins账号来执行脚本最终进程会被干掉,而通过SSH发布到另外一台机器上就不会有问题的原因。

解决方法

解决方法其实也很简单,上面的文档里也有写。贴一段关键代码做示例:

#!/bin/bash

# 省略无关代码...
BUILD_ID=dontKillMe ${JAVA_HOME}/bin/java $JAVA_OPS  -jar $JARFILE $@ > ${logname}  &
# 省略无关代码...

如上,只需要在启动命令的前面加一句BUILD_ID=dontKillMe即可。

✎﹏ 本文来自于 momo314和他们家的猫,文章原创,转载请注明作者并保留原文链接。