Zeek进程收到SIGTERM/SIGKILL信号后自动重启的问题如何解决
问题原因
- 带方括号的
[zeek]进程是僵尸进程,并非被自动重启。进程收到终止信号后已经停止执行,只是父进程未调用wait()/waitpid()系统调用回收其退出状态,进程描述符残留在系统进程表中,内核会为这类已终止但未被回收的进程名加上方括号标记。 - 手动执行
kill可以正常终止进程的核心原因是:手动执行命令时,Zeek的父进程是当前shell,shell会自动回收子进程的退出状态,不会残留僵尸进程;而通过Python脚本启动的Zeek父进程为Python脚本,若脚本发送终止信号后未主动回收子进程资源,就会产生僵尸进程。 - 若启动Zeek时使用
subprocess.Popen未配套调用wait()/communicate(),或使用os.fork派生进程后无回收逻辑,必然会触发该问题。如果Zeek并非由Python脚本启动,而是由systemd、supervisor等守护管理服务托管,发送终止信号后守护进程会自动拉起Zeek,也会出现进程无法终止的表象。
解决方案
方案1:完善Python脚本进程管理逻辑(推荐)
如果Zeek由Python脚本直接启动,发送终止信号后必须新增进程回收逻辑,示例参考如下:
import subprocess import time # 启动Zeek进程 zeek_proc = subprocess.Popen(["zeek", "-i", "eth0"], shell=False) # 终止逻辑触发时 # 发送SIGTERM信号优雅终止 zeek_proc.terminate() # 最多等待5秒让进程正常退出 try: zeek_proc.wait(timeout=5) except subprocess.TimeoutExpired: # 超时未退出则发送SIGKILL强制终止 zeek_proc.kill() # 强制终止后再次回收进程资源 zeek_proc.wait() # 延迟后重新拉起Zeek time.sleep(3) new_zeek_proc = subprocess.Popen(["zeek", "-i", "eth0"], shell=False)
如果Zeek由第三方守护服务托管,先停止对应守护服务的托管规则,再执行进程终止操作即可。
方案2:清理已存在的僵尸进程
僵尸进程本身无法通过kill信号直接清理,需要终止其父进程触发资源回收:
- 执行
ps -ef | grep '\[zeek\]'获取僵尸进程对应的PPID(父进程ID) - 确认父进程为未做回收逻辑的Python脚本后,重启Python脚本即可自动清理残留的僵尸进程。
内容的提问来源于stack exchange,提问作者4bdl
相关产品推荐
相关产品推荐

