filebeat的nohup进程自动停止的问题
异常分析
正常运行了几天的两台机器的filebeat突然同时终止了,没有任何人杀这个进程,在那个时间段也没有出现cpu、内存等资源使用率的变化,而下游的logstash也是一直运行正常。
当时启动filebeat在后台运行的命令是:
nohup filebeat -c /data/nlu/filebeat/filebeat.yml -e > /data/nlu/filebeat/filebeat.log 2>&1 &
把nohup命令的特性了解一下才知道是今天自己关闭了前几天启动这个命令的xshell窗口,导致了nohup进程也被终止。
nohup进程在前台运行:
nohup filebeat -c /data/nlu/filebeat/filebeat.yml -e > /data/nlu/filebeat/filebeat.log 2>&1
此时你不能在shell进行任何输入。
如果要在后台运行则在这个命令加上&
,此时可以在shell进行输入。
nohup filebeat -c /data/nlu/filebeat/filebeat.yml -e > /data/nlu/filebeat/filebeat.log 2>&1 &
但此时仍可能存在问题,如果你通过ssh协议连接到了终端,比如说通过xshell连接到了终端,连接登陆时的用户是root,启动nohup进程的用户也是root。
此时你关闭终端,断开ssh连接,会导致这个nohup进程也同时终止。因为断开连接时,会发送SIGHUP
信号给当前shell的作业列表的所有进程,nohup进程接收到SIGHUP
信号后终止。
故障复现
重新启动一个nohup进程,查找到这个nohup进程ID为48199
,父进程ID为41965
:
# ps -ef | grep filebeat
root 48199 41965 0 22:05 pts/2 00:00:00 /data/nlu/filebeat/filebeat -c /data/nlu/filebeat/filebeat.yml -e
root 50124 41965 0 22:08 pts/2 00:00:00 grep --color=auto filebeat
而进ID为41965
的进程就是我们登陆这个shell时的进程,nohup进程时这个进程的一个子进程(下面列表中的第一个):
# ps -ef | grep 41965
root 41965 41931 0 21:55 pts/2 00:00:00 -bash
root 48199 41965 0 22:05 pts/2 00:00:00 /data/nlu/filebeat/filebeat -c /data/nlu/filebeat/filebeat.yml -e
root 50039 48871 0 22:08 pts/4 00:00:00 grep --color=auto 41965
使用jobs
命令查看此时该shell的作业列表:
# jobs
[1]+ Running nohup /data/nlu/filebeat/filebeat -c /data/nlu/filebeat/filebeat.yml -e > /home/dpc/elk/filebeat/filebeat.log 2>&1 &
另开一个窗口登陆到终端,然后用strace
命令跟踪nohup进程的系统调用:
# strace -e signal -p48199
strace: Process 48199 attached
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=41965, si_uid=0} ---
rt_sigreturn({mask=[]}) = 202
+++ exited with 0 +++
直接关闭启动nohup进程的端口,此时是终止这个shell的进程,此时也会把这个进程的所有子进程也给终止。可以看到系统会发送SIGHUP
命令给当前shell的使nohup进程终止。
此时再查看父进程,将查不到该进程:
# ps -ef | grep 41965
解决办法
解决终端关闭导致后台的nohup进程停止的有两种办法。
第一种是,在关闭xshell终端之前,先用exit
命令断开ssh连接,然后就可以关闭终端了。但该方法一定程度上仍可能存在直接关闭终端导致nohup进程终止的危险。
第二种是,在原来的命令之前加上disown
参数,这个参数将会使启动的nohup进程从当前shell的作业列表中清除,从而避免nohup进程在关闭这个shell时接收到SIGHUP
信号。
nohup filebeat -c /data/nlu/filebeat/filebeat.yml -e > /data/nlu/filebeat/filebeat.log 2>&1 & disown
参考
[1] 5 Ways to Keep Remote SSH Sessions and Processes Running After Disconnection
[2] filebeat进程运行一段时间后自动退出问题解决方法
[3] Does linux kill background processes if we close the terminal from which it has started?