我不得不面对以下问题:我们有一个由bash脚本启动的Java应用程序。 这个应用程序应该作为守护进程运行,所以我们有一个暴发户的工作来启动它。
start on runlevel [2345] stop on runlevel [!2345] #tell upstart we will fork later, so it will mangage the pids. expect fork #If the daemon stoppes unexpectedly, restart it! respawn script #The framework will only work, if we start it from this directory. cd /usr/lib/app-dir nohup ./appStartScript.sh &> /dev/null & #send an upstart event, in case we will chain this job later emit app_running end script
有时,应用程序停止工作。 没有一个.hprof文件,如果虚拟机崩溃,也不会创build一个hserr文件。 暴发户申报为运行,
appDeamon start/running, process 1131
但是PID没有在ps -aux中列出。 (另外,新贵不能停止appDeamon的进程。)
我想知道:a)为什么暴发户认识到应用程序崩溃? b)是否有可能强迫新手重新启动应用程序,即使具有给定PID的进程不再存在? (到目前为止,我们需要重新启动整个服务器。)
我们的系统是Ubuntu Linux 10.04.1 LTS。
这是守护程序通常发生的事情:
问题是Java不提供fork的机制,所以这个经过testing的模式不能正确实现。 在执行Java守护进程时,您不得不立即为进程提供后台服务(即脚本中的&符号)。 新贵基本上开始了这个过程,然后立即忘了 – 这个过程没有办法指示Upstart是否成功启动。
解决这个问题的唯一方法就是开始这个过程,将其背景化,然后检查它是否仍在运行,以确定它是否成功。 当然了,是确定何时检查它是否仍在运行。 简单的解决scheme是这样的:
#!/bin/sh java MyClass >/dev/null 2>&1 & PID=$! sleep 3 if kill -0 $PID; then exit 0 else exit 1 fi
有更复杂的scheme来确定何时检查进程,如使程序closuresstdout和stderr,或者在完成启动例程时创buildPID文件,并在启动脚本中等待这些事件。
最简单的解决scheme是修改你的Upstart脚本,如下所示:
script cd /usr/lib/app-dir nohup ./appStartScript.sh &> /dev/null & PID=$! sleep 3 if kill -0 $PID; then emit app_running exit 0 else exit 1 fi end script
为什么你的应用程序需要由bash脚本启动? 新贵需要知道你的应用分叉多less次。 你已经告诉它它没有fork(因为你没有指定' expect '节),但是你已经分叉了(因为你已经在脚本部分指定了' & ',所以Upstart无法跟踪PID 。
请参见: