解决jenkins自动杀掉衍生进程:[Exec exit status not zero. Status [1]]、[Exec exit status not zero. Status [137]]

在这里插入图片描述

  1. ERROR: Exception when publishing, exception message [Exec exit status not zero. Status [1]]
  2. ERROR: Exception when publishing, exception message [Exec exit status not zero. Status [137]]

这俩个错误大家遇到的应该不多吧,最近在用jenkins向一个远程服务器的Tomcat里部署启动项目时我就遇到了,顺便给大家讲讲这是如何解决的。

先看一下整体环境:

在这里插入图片描述

解释:jenkins通过pipeline脚本中使用SSH(sshPublisher)函数调用目标服务器中的一个start.sh的启动脚本,这个脚本向另一个run.sh脚本中传递一个参数字符串【start】。run.sh脚本通过判断字符串【start】来确定去执行Tomcat中的启动脚本,也就是startup.sh

正常逻辑中,当执行第一个start.sh时,按照如上流程将正常启动Tomcat服务器,但是在jenkins中却出现了如上报错。

原因

在jenkins的官方原文中是这样描述的:

This feature is available since 1.260

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.

This can be done as a parameter to the “java” binary when starting Jenkins:

java -Dhudson.util.ProcessTree.disable=true -jar jenkins.war

Depending on how you run your container, this can be different. In the distributed build environment, this system property needs to be set on slave JVMs.

Older versions of Hudson (<1.315) used the Java Property hudson.util.ProcessTreeKiller.disable, but the class ProcessTreeKiller has been depecated since. For compatibility reasons, currently both property names are supported (as of version 1.404).

How it works
The ProcessTreeKiller takes advantage of the fact that by default a new process gets a copy of the environment variables of its spawning/creating process.

It sets a specific environment variable in the process executing the build job. Later, when the user requests to stop the build job’s process it gets a list of all processes running on the computer and their environment variables, and looks for the environment variable that it initially set for the build job’s process.

Every job with that environment variable in its environment is then terminated.

If your build wants to leave a daemon running behind…
A convenient way to achieve that is to change the environment variable BUILD_ID which Jenkins’s ProcessTreeKiller is looking for. This will cause Jenkins to assume that your daemon is not spawned by the Jenkins build. For example:

大概意思就是当jenkins执行完主进程时,会杀掉该主进程,同时也会杀死主进程下的所有子进程

如上图我们可以看到这样的场景下,存在着3个子进程分别是 start.shrun.shstartup.sh,因为在jenkins执行完start.sh时就会关闭通道,所以导致run.shstartup.sh均无法启动,这才引发了一系列上面的报错异常。

解决办法

根据上面的原因我们需要做到如下两点即可解决:

  1. 将第一个进程脚本,也就是start.sh中调用run.sh的语句加上后台运行,当然run.sh中调用startup.sh的语句也需要加上。如下图:(nohup即可)

在这里插入图片描述

  1. 由于jenkins执行远程服务器脚本时会把自身服务器的环境配置携带过来导致无法正常启动Tomcat中startup.sh脚本,所以还需要在执行startup.sh的脚本中加入环境变量的导入,也就是在run.sh中加入。如下:
    在这里插入图片描述

完成以上两个步骤,即可解决jenkins自动杀掉衍生进程导致的一系列报错了。

猜你喜欢

转载自blog.csdn.net/jxysgzs/article/details/115240674