最近我养成了杀死进程的习惯
fuser -k -n tcp $PORT
这很难杀死错误的进程。我更喜欢这个,而不是摆弄一个 pid 文件,它可能仍然存在,也可能不存在,或者可能包含也可能不包含正确的 pid(好吧,我在这里有点戏剧性:-)
然而,我偶然发现的典型停止脚本仍然使用 pidfile。
我是否缺少 pidfile 方法的一个重要功能或 fusion 的错误功能approach
。我最好的猜测是fuser
不可用。虽然从搜索引擎结果来看,bsd、debian、suse、centos、aix、solaris 似乎都有。
答案1
命令fuser
选项-n <file|udp|tcp>
是 Linux 特定的,而基于 PID 文件的解决方案是许多 Unix 变体中的传统解决方案,因此保证了非常可移植。
至少在 Debian 中,该fuser
命令位于psmisc
包中,该包已被指定为“可选”,因此不能期望它始终存在于所有系统中。
答案2
除了 telcoM 提到的内容之外,这种方法还有两个潜在问题,它们都与名为 的套接字选项有关SO_REUSEPORT
。
此套接字选项允许多个进程(所有进程都必须设置该选项)绑定到同一端口,并将传统上由主进程完成的连接负载平衡卸载到内核。
由此产生的两个潜在问题是:
对于使用基于进程的并行性(例如 NGinx)并使用此选项的服务器,连接到套接字的 PID 通常是主进程的子进程,而不是主进程本身。在这种情况下,您的
fuser
方法将杀死所有子进程,但不会向主进程发送任何信号,这可能根本不会终止服务(如果主进程只是重新启动子进程),或者可能导致它被关闭以导致问题的方式(代码可能假设子进程死亡指示致命错误,并使用与主进程本身接收信号不同的退出路径)。这可能会杀死您想要的其他程序。这种情况不太可能是一件坏事(您可以杀死的唯一“其他”程序可能是恶意软件),但值得考虑。