场景
在Hudson中新建一个Job用于构建Web工程,在Job的构建脚本的最后会启动Jetty,观察发现Jetty启动之后一小段时间,进程就终止了。
 
环境
CentOS 6,Hudson 3.0.1,Jetty 8,Oracle JDK 1.6
 
分析
刚开始在Job中启动Jetty的方式是在Ant构建脚本build.xml中调用一个shell脚本进行应用部署和容器重启。整个Job的构建过程正常,Jetty终止以后也查不到任何异常日志。
 
后来尝试在Job的build step中直接使用"Execute shell"去调用shell脚本,发现Job的Console output出现如下提示:
Process leaked file descriptors. See http://wiki.hudson-ci.org/display/HUDSON/Spawning+processes+from+build for more information
查看上面的链接以及Google相关资料,发现Hudson在Job构建结束之后,kill所有未终止的衍生进程。
 
Hudson与子进程之间使用三根管道通信(stdin/stdout/stderr),这样Hudson可以捕捉到子进程的输出。由于子进程可能往stdout写入大量数据然后立即退出,Hudson为了完整读取子进程的输出,会在用于子进程stdout的管道上等待EOF。这样,无论子进程由于什么原因退出,系统将关闭进程使用的文件描述符,因而Hudson总是可以收到EOF。
 
但是当子进程A在后台fork出另一个进程B的时候(比如启动一个daemon进程),情况就出现一些变化。由于进程B会继承进程A的文件描述符,如果进程B没有关闭这些描述符,即使进程A退出,这些描述符依然是打开的,Hudson将不会在相应管道上收到EOF。通常一个实现良好的daemon会关闭所有文件描述符以避免这个问题,但是总有一些实现没有遵循这个规则。在旧版本的Hudson上,这个问题将导致Job无法结束,Hudson一直在等待EOF;新版本则会打印出上面的"leaked file descriptors"警告,然后Job构建过程继续。
 
看来Jetty可能没有关闭继承的文件描述符,Hudson在Job构建过程结束后认为Jetty进程未终止,因而将其kill掉了。上述链接指向的Hudson wiki页面上提到可以使用daemonize工具将程序作为实现良好的daemon进程运行以避免这个问题。
 
在Hudson另一wiki页面上进一步描述了Hudson杀掉衍生进程的情况。Hudson在执行Job时会设置一系列环境变量,这些环境变量将被Job衍生出的进程继承。Hudson在kill衍生进程的时候会查看进程的环境变量,如果找到它之前设置的环境变量,则将其杀掉。Wiki上给出了一个简单的方法来避免进程被kill掉:修改Hudson设置的环境变量BUILD_ID的值,从而让Hudson认为此进程不是由Job的构建过程衍生的。如:
BUILD_ID=dontKillMe /usr/apache/bin/httpd
另外,在此wiki上还提到可以在启动Hudson的时候通过Java选项来关闭Hudson杀掉所有衍生进程的这个功能:
 java -Dhudson.util.ProcessTreeKiller.disable=true -jar hudson.war
 
解决方案
1.安装daemonize包,使用daemonize命令wrap Jetty的启动指令。
daemonize ${jetty_bin} start
2.在启动Jetty之前,修改BUILD_ID环境变量。
# set BUILD_ID, or Hudson will kill any child processes
# that are started by build steps.
BUILD_ID="dontKillMe" ${jetty_bin} start
3.设置Java选项hudson.util.ProcessTreeKiller.disable为true。
 
References
3.daemonize — A tool to run a command as a daemon.http://software.clapper.org/daemonize/
 

在Hudson Job中启动daemon进程的更多相关文章

  1. Linux中创建Daemon进程的三种方法

    什么是daemon进程? Unix/Linux中的daemon进程类似于Windows中的后台服务进程,一直在后台运行运行,例如http服务进程nginx,ssh服务进程sshd等.注意,其英文拼写为 ...

  2. erlang supervisor中启动普通的进程

    文字部分转自: http://1234n.com/?post/qou3eb supervisor的子进程 一开始使用supervisor的时候,我用的是init/1返回子进程规格列表的方式,并且所有子 ...

  3. jenkin构建项目执行脚本后,脚本中启动的进程也随之关闭的解决办法

    问题描述: 之前用jenkins构建项目(maven项目)后都是通过ssh先将war文件推送到远程服务器,然后执行远程的脚本(更新项目,重启tomcat),一直没有出现问题,今天使用jenkins构建 ...

  4. Qualcomm 8X camera daemon进程浅析

    Camera 先看一下抽象层的主要流程: 首先启动一个守护进程 int qcamsvr_start(void)( qcamsvr.c) { 1. server_fd = open(server_dev ...

  5. python中的daemon守护进程实现方法

    原文参考:http://blog.csdn.net/tao_627/article/details/49532021 守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理 ...

  6. Android系统在新进程中启动自定义服务过程(startService)的原理分析

    在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验.Android系统为我们提供了一个Service类,我们可以实现 ...

  7. Docker学习笔记 - 在运行中的容器内启动新进程

    docker psdoker top dc1 # 容器情况# 在运行中的容器内启动新进程docker exec [-d] [-i] [-t] 容器名 [command] [args]docker ex ...

  8. 在linux中安装jdk以及tomcat并shell脚本关闭启动的进程

    在命令行模式中输入uname -a ,如下图,当界面展示i386就说明本linux系统为32版本,就在官网下载对应jdk版本,或者直接到我的网盘上下载http://pan.baidu.com/s/1c ...

  9. C#/.NET 中启动进程时所使用的 UseShellExecute 设置为 true 和 false 分别代表什么意思?

    原文:C#/.NET 中启动进程时所使用的 UseShellExecute 设置为 true 和 false 分别代表什么意思? 在 .NET 中创建进程时,可以传入 ProcessStartInfo ...

随机推荐

  1. SQL注入的各种类型的检测方式

    #SQL注入各个类型检测方式 http://127.0.0.1/day6/1.php?id=1 union select 1,name,pass from admin 数字型 数字型不用特意加字符,直 ...

  2. (转)XML中必须进行转义的字符

    场景:在工作中接触到很多xml文件,为了更好的操作这些文件,所有很有必要熟知xml文件的相关语义. 1 引入 编写XML代码经常遗漏的常识: XML实体中不允许出现"&", ...

  3. 【JAVASCRIPT】React入门学习-文本渲染

    摘要 react 学习包括几个部分: 文本渲染 JSX 语法 组件化思想 数据流 文本渲染 1. 纯文本渲染 <!DOCTYPE html> <html> <head&g ...

  4. 【PHP】数组用法(转)

    摘要: 说明数组遍历方法foreach,while,for,推荐使用foreach(PHP内部实现,简单速度最快,还可以遍历类属性).以及一些常用方法current,prev,next,end,key ...

  5. Python学习记录----IDE安装

    摘要: 安装eric5 一 确定python版本 安装的最新版本:python3.3 下载连接:http://www.python.org/getit/ 二 确定pyqt版本 安装的最新版本:PyQt ...

  6. Easy DataGrid 实现动态列、行

    Easy DataGrid 实现动态列.行 前端代码: <title>展示销售的实时数据</title> <script type="text/javascri ...

  7. 用gensim学习word2vec

    在word2vec原理篇中,我们对word2vec的两种模型CBOW和Skip-Gram,以及两种解法Hierarchical Softmax和Negative Sampling做了总结.这里我们就从 ...

  8. Android异步处理技术

    前言: 在移动端开发中,我们必须正确处理好主线程和子线程之间的关系,耗时操作必须在子线程中完成,避免阻塞主线程,导致ANR.异步处理技术是提高引用性能,解决主线程和子线程之间通信问题的关键. 通常在如 ...

  9. [补档][COGS 426]血帆海盗

    [COGS 426]血帆海盗 题目 传送门:http://cogs.pro/cogs/problem/problem.php?pid=426 随着资本的扩大,藏宝海湾贸易亲王在卡利姆多和东部王国大陆各 ...

  10. nopCommerce 3.9 大波浪系列 之 微信公众平台登录插件

    一.简介 插件源码下载:点击下载 微信公众平台网站授权帮助地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp142114084 ...