开发环境中的rabbitmq总是会挂掉,rabbitmq的执行都是ssh远程登录执行命令:

rabbitmq-server &

认为加了&,进程会在后台执行不会受到终端的影响。所以不知道什么问题,后面想到使用strace查看该进程到底在退出时遇到了什么。

使用strace记录下日志,到第二天的时候果然RMQ再次倒下。查看日志,看到最后一行内容:

--- SIGHUP (Hangup) @ 0 (0) ---

好了,这个就是该进程的'临终遗言'了。看来是被某个进程发来的SIGHUP信号弄死的。【系统对SIGHUP信号的默认处理是终止收到该信号的进程。所以若程序中没有捕捉该信号,当收到该信号时,进程就会退出。】

后面查询资料得知:

  • 内核驱动发现终端(或伪终端)关闭,给终端对应的控制进程(bash)发 SIGHUP
  • bash 收到 SIGHUP 后,会给各个作业(包括前后台)发送 SIGHUP,然后自己退出
  • 前后台的各个作业收到来自 bash 的 SIGHUP 后退出(如果程序会处理 SIGHUP,就不会退出)

看来我们可怜的进程的'死因'就是这个了,有点荡气回肠。

那么我们现在就可以采取两种方式(我所想到的)来让后面的进程不再受到'死因'的影响:

  • 使用nohup命令

    nohup rabbitmq-server &
  • 使用setsid命令
    setsid rabbitmq-server &

我们可以通过strace看到RMQ进程在使用nohup命令时,会收到SIGHUP信号,但是进程不受影响。使用setsid命令时,RMQ进程是不会收到SIGHUP进程的。

相关资料:关闭终端后,后台作业退出的分析

05-11 10:57