运行带有Runit / daemontools或其他进程监督框架的JBoss 6

我试图用runit来守护JBoss。

我使用/opt/jboss-6.1.0.Final/bin/run.sh脚本启动服务器。 当我从命令行中这样做的时候,JBoss不会分离(这是我们想要的),并且在CTRL + C被按下时也会closures。 理论上来说是一个完美的候选人使用runit。

除非我试图让runitclosuresJBoss,否则一切正常。 当我发出命令sv stop jboss没有任何反应。 Runit认为这个过程已经停止,但是jboss继续正常运行。

我没有做任何特别的run脚本。 这是我的runit run脚本:

 #!/bin/sh exec 2>&1 exec /opt/jboss-6.1.0.Final/bin/run.sh -c standard -b 0.0.0.0 

查看jboss_init_redhat.sh脚本, start部分提到了./bin/run.sh但是停止部分具有以下文本:

 JBOSS_CMD_STOP=${JBOSS_CMD_STOP:-"java -classpath $JBOSSCP org.jboss.Shutdown --shutdown"} 

任何想法,我可以尝试?

对于任何有相似约束力的人,我找出问题所在。 我正在解释我如何得到答案,因为我认为它可以帮助解决其他问题。

使用runit启动JBoss之后,如果执行ps aux | grep jboss ps aux | grep jboss这是结果:

 # ps aux | grep jboss root 1855 0.0 0.0 120 24 ? Ss 11:23 0:00 runsv jboss root 1856 0.0 0.0 144 44 ? S 11:23 0:00 svlogd -tt /var/log/jboss root 1857 0.0 0.0 10820 1168 ? S 11:23 0:00 /bin/sh /opt/jboss-6.1.0.Final/bin/run.sh -c standard -b 0.0.0.0 root 1926 178 1.9 1501080 78560 ? Sl 11:23 0:05 java -server -Xms128m -Xmx1024m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n -Djava.net.preferIPv4Stack=true -Dprogram.name=run.sh -Dlogging.configuration=file:/opt/jboss-6.1.0.Final/bin/logging.properties -Djava.library.path=/opt/jboss-6.1.0.Final/bin/native/lib64 -Djava.endorsed.dirs=/opt/jboss-6.1.0.Final/lib/endorsed -classpath /opt/jboss-6.1.0.Final/bin/run.jar org.jboss.Main -c standard -b 0.0.0.0 root 1950 0.0 0.0 61224 764 pts/0 S+ 11:23 0:00 grep jboss 

现在执行sv status jboss并记下sv报告的pid:

 # sv status jboss run: jboss: (pid 1857) 17s; run: log: (pid 1856) 17s 

sv认为jboss的pid是1857,但是检查ps的输出,jboss的实际pid是1926,启动jboss的shell是pid,是1857.这就是问题所在, run.sh脚本做了一些有趣的事情。

如果您深入研究run.sh脚本,在涉及可怕的java classpath连接之后,您可以find以下摘录:

 # Execute the JVM in the foreground eval \"$JAVA\" $JAVA_OPTS \ -Djava.endorsed.dirs=\"$JBOSS_ENDORSED_DIRS\" \ -classpath \"$JBOSS_CLASSPATH\" \ org.jboss.Main "$@" JBOSS_STATUS=$? 

它使用eval而不是exec来执行jvm! 这就是为什么它产生了一个单独的进程,并且runit无法正确控制它。

只要将脚本的那部分改为:

 # Execute the JVM in the foreground exec ${JAVA} $JAVA_OPTS \ -Djava.endorsed.dirs=${JBOSS_ENDORSED_DIRS} \ -classpath ${JBOSS_CLASSPATH} \ org.jboss.Main "$@" JBOSS_STATUS=$? 

和presto! 对exec的调用会将自身replace为exec的进程,runit将能够正确控制进程。

当我用exec命令replaceeval时,虽然java dir是正确的,但是eval正在工作,所以我得到了exception。 问题是看我什么时候使用eval 2进程在jboss启动时运行。 请指教。 ./standalone.sh:289:exec:“/app/dms/java/jdk1.7.0_60/bin/java”:not found