Home systemd 关闭服务
Post
Cancel

systemd 关闭服务

Kill Services

如何杀死一个守护进程?

如果守护进程(一套服务)只存在一个单一的进程中,则直接对其发送信号即可。使用 killkillall 命令。 killall是根据进程名发送信号,所有相同名称的进程都会收到。

如果守护程序创建了pid文件,那么规范一些的操作应当是根据pid文件中的pid号去发信号。pid文件一般在 /var/run/*.pid, 如/var/run/atd.pid,/var/run/crond.pid,/var/run/docker.pid,/var/run/sshd.pid等。

不过,通常情况可能更复杂,因为守护程序一般都会创建一些子进程,如cron和at作业,cgi脚本等。如果只杀死了它们的主进程, 那么它们衍生出的子进程可能会主动关闭,也可能会交给init程序管理,(这取决于程序自己的行为逻辑),如果这些子进程交给 init进程管理了,就难以追踪了。

而在systemd中,支持对整个服务的所有进程发送信号,(得益于systemd使用的cgroups机制),使用命令 systemctl kill 即可。默认发送 SIGTERM 信号。信号名在这里可以不加SIG前缀。

1
2
3
4
5
6
# systemctl kill [PATTERN] ...
#    Send a signal to one or more processes of the unit. Use --kill-who= to select which process to kill. 
#     Use --signal= to select the signal to send.

systemctl kill crond.service
systemctl kill -s SIGKILL crond.service

这样,整个service中所有的进程都会收到相应的信号。如果只希望发送给主进程,则可以使用

1
systemctl kill -s HUP --kill-who=main crond.service

传统方式中,守护程序的子进程的终止通常需要守护程序配合来完成。如果守护程序没能正确终止子进程,那么清理起来就非常麻烦, 而到了systemd中,可以很方便的解决这类问题,它能够对一个服务的所有进程发信号。

Stop Services

systemctl killsystemctl stop 的关联,kill本身的直接释义是向service中的进程发信号,发送SIGTERM信号一般可以关闭, 如果发SIGKILL,可以强制结束。 而 stop方式则是通过官方配置的方式来关闭服务,即调用服务文件中配置了ExecStop=的stop命令。 通常stop应该就足够了。Kill是更激烈的版本,适用于不希望通过stop命令关闭服务,或者当服务以其他方式被 hosed 或挂起时。

This post is licensed under CC BY 4.0 by the author.