我有一个 node.js 脚本,我想在 Funtoo 系统上对其进行守护进程化(我标记为 Gentoo,因为我认为这里与 Gentoo 相比,Funtoo 没有什么特别之处),我使用以下初始化脚本执行此操作:
#!/sbin/runscript
depend(){
need redis
}
start(){
ebegin "Starting myapp"
NODE_ENV="prod" start-stop-daemon --start --background --make-pidfile -1 /var/log/myapp.log -2 /var/log/myapp.error --chdir /opt/myapp --pidfile /var/run/myapp.pid --exec /usr/bin/node -- /opt/myapp/myapp.js
eend $?
}
stop(){
ebegin "Stopping myapp"
start-stop-daemon --stop --pidfile /var/run/myapp.pid --exec /usr/bin/node -- /opt/myapp/myapp.js
eend $?
}
这样,我可以使用 init 脚本或 rc-service 顺利启动和停止服务。然后,为了确保它在发生错误时保持运行,我使用具有以下配置的 monit:
check process myapp with pidfile "/var/run/myapp.pid"
start program = "/sbin/rc-service myapp start"
stop program = "/sbin/rc-service myapp stop"
if failed port 8123 protocol HTTP
request /myapp.client.js
with timeout 10 seconds
then restart
我可以看到 monit 确实成功监视了应用程序,并检测到它何时出现故障,因为当它崩溃时,我的日志中就会填满以下内容:
Apr 24 21:05:35 [monit] 'myapp' trying to restart_
Apr 24 21:05:35 [monit] 'myapp' start: /sbin/rc-service_
Apr 24 21:06:05 [monit] 'myapp' failed to start_
以详细模式从控制台运行 monit 不会提供任何更有用的信息:
'myapp' Error testing process id [30106] -- No such process
'myapp' process is not running
'myapp' trying to restart
'myapp' Error testing process id [30106] -- No such process
'myapp' Error testing process id [30106] -- No such process
'myapp' start: /sbin/rc-service
'myapp' Error testing process id [30106] -- No such process
'myapp' Error testing process id [30106] -- No such process
* WARNING: myapp has already been started
似乎发生的情况是它从未运行停止命令,因此 pid 文件仍然存在,因此start-stop-daemon
不会将其调出。但是,我并不完全确定如何更改此行为,或者我是否配置错误(我使用 Gentoo/Funtoo 多年,但这是我第一次编写 init 脚本,也是我第一次使用 monit)。
所以,简而言之,我缺少什么来让 monit 成功重启我的服务?
更新:
@aseq 的回答让我思考了一会儿,我不太清楚为什么我以前没有想到这一点。只需将start program
配置文件中的行更改为:
start program = "/sbin/rc-service myapp restart"
使其按预期运行。日志仍然有点不顺畅,因为在尝试停止时start-stop-daemon
会发出抱怨no matching processes found
,但它仍然会恢复。
答案1
您走的路是正确的,因为 PID 文件仍然存在,所以 monit 无法启动。
我以前遇到过这些问题,我使用的解决方案是为特定服务创建一个初始化脚本,使用类似 /etc/init.d/skeleton(在 debian 上)作为模板(或 rc.local),确保正在创建和删除 PID 文件(使用 start-stop-daemon 等)。
我认为没有其他解决方案,因为 monit 不处理删除或创建 PID 文件。无论您使用哪个脚本来启动和停止服务,它都需要正确创建和删除 PID 文件。