最近一直在测试,发现有个节点kafka server进程莫名的自动挂了,其它kafka server正常。查看日志,没有异常错误日志输出,在日志中发现了kafka shut down 原因是接收到了SIGHUP停止的信号。日志如下:
INFO Terminating process due to signal SIGHUP (org.apache.kafka.common.utils.LoggingSignalHandler)
下载kafk2.1源码,LoggingSignalHandler源码如下:
-kafka注册了java 信号捕获类,当接收到对应信号kafka server进行处理。怀疑是启动server后退出终端造成的。启动命令为:
bin/kafka-server-start.sh config/server-1.properties &
…
bin/kafka-server-start.sh config/server-2.properties &
参照官方,使用&后台进程启动,我们认为后台进程退出shell终端进程不会退出。百度找到了一篇对SIGHUP信号的解释:
linux sighup 信号
在读UNIX网络编程卷一 13.4 守护进程编写时, 书中写到,这里必须忽略SIGHUP信号,因为会话头进程(及首次fork产生的子进程,通过setsid 成为会话头进程)终止后,会向其会话中所有进程(及再次fork产生的子进程)发送SIGHUP信号。
- 1
在这里有个疑问,SIGHUP信号在第一个父进程退出时,不会发送吗? SIGHUP信号到底什么情况下会产生?
翻阅资料得到答案:
1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进程)
2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程
3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。
书中所描述的是第二种情况,即 session 首进程退出。
那个 第一个父进程退出,是什么情况呢?
-
不是第一种情况, 因为不是终端关闭, 不是第三种情况,因为父进程退出,进程组只有一个运行的子进程。
-
父进程会是session首进程吗? 答案是,不是,因为我们运行该程序,一般是在shell中,通过命令进行,这时,shell 将是会话首进程。
在环境中使用&启动退出终端,问题重现。
https://mp.csdn.net/editor/html/113615914 这篇博客介绍了测试nohup , &及功效。
结论:kafka 使用&启动后退出shell窗口后进程收到了sighup信号,进程自动关闭,其它节点我们是通过ssh过去使用exit退出,执行exit后,进程变成孤儿,不会收到sighup信号从而没有自动关闭进程。我们同时使用nohup和&命令启动后,节点正常运行,没有退出。