场景
在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. 【SignalR学习系列】2. 第一个SignalR程序

    新建项目 1.使用VisualStudio 2015 新建一个Web项目 2.选择空模板 3.添加一个新的SignalR Hub Class (v2)类文件,并修改类名为ChatHub 4.修改Cha ...

  2. javascript中的闭包(Closure)的学习

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面是我在网上通过学习阮一峰老师的笔记,感觉总结很不错,特记录于此. 一.变量的作用域 要理解 ...

  3. word2vec原理(二) 基于Hierarchical Softmax的模型

    word2vec原理(一) CBOW与Skip-Gram模型基础 word2vec原理(二) 基于Hierarchical Softmax的模型 word2vec原理(三) 基于Negative Sa ...

  4. PHP输出函数print, printf, sprintf的区别

    PHP中常用的字符串输出方式是:使用echo和print两种方法来显示字符串.如果涉及格式化输出操作,还可以试用printf和sprintf函数. 一.先说echo和print两种方法 print的语 ...

  5. jvm系列 (二) ---垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...

  6. Password

    Description Rivest是密码学专家.近日他正在研究一种数列E = {E[1],E[2],--,E[n]}, 且E[1] = E[2] = p(p为一个质数),E[i] = E[i-2]* ...

  7. 《开发技巧》WEB APP开发调试技巧

    前言 随着html5和nodejs的兴起.web APP越来越火,一套代码可以多平台使用.减少了很大的开发成本.很多APP中也集成了很多的html5页面,增强很高的应用体验.所以移动端页面也事关重要! ...

  8. Cox回归模型【生存分析】

    参考:<复杂数据统计方法--基于R的应用> 吴喜之 在生存分析中,研究的主要对象是寿命超过某一时间的概率.还可以描述其他一些事情发生的概率,例如产品的失效.出狱犯人第一次犯罪.失业人员第一 ...

  9. HBase集群安装部署

    0x01 软件环境 OS: CentOS6.5 x64 java: jdk1.8.0_111 hadoop: hadoop-2.5.2 hbase: hbase-0.98.24 0x02 集群概况 I ...

  10. 解决Visual Studio For Mac Restore失败的问题

    之前就了解到微软出了mac版的VS,没太多的关注,自己也就是使用 DotNet Core SDK + VS Code 做一些小demo. 前两天发布了DotNet Core 2.0 ,Visual S ...