如何配置systemd以在重载时终止并重新启动守护进程?


12

我有一个老式的守护程序,我想使用systemd进行控制。当其配置文件更改时,需要将其杀死并重新启动。换句话说,在编辑配置文件后,systemctl reload MYSERVICE应终止该进程并重新启动它。

尝试1:尝试使用默认值。这告诉systemd如何启动守护程序,而不是如何重新加载它。

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

其结果是,startrestart工作,但reload给出了这样的错误:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

尝试2:告诉它如何终止进程。这杀死了进程,但是systemd不会为我重新启动它。

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...其次是...

# systemctl daemon-reload
# systemctl reload MYSERVICE

...杀死进程,但不会自动重启。

尝试3:也使用ExecReload重新启动该过程。失败的原因如下:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

...我收到的错误消息...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

我希望会有ReloadType = kill_and_restart之类的东西,但是没有这种运气。

如何告诉systemd在重新加载时杀死并重新启动守护进程?


是否真的需要把它塞入重载位置,而不完全适合?您不能使守护程序表现得明智吗?
迈克尔·汉普顿

感谢@MichaelHampton,但这不是我可以重写程序的情况。感谢您的有益建议。就是说,我敢肯定这是一个常见的systemd用例,一个规范的答案可能会帮助很多人。
TomOnTime '16

1
我确定答案可能会帮助某人,所以我赞成这个问题。我只是不确定这是否是常见的用例。使用systemd大约有五年了,几乎是从它在世界上发布的那一天开始的,这是我第一次回想起有人尝试过这种情况。由于缺少细节,我可能会误解某些东西。
迈克尔·汉普顿

Answers:


16

答案是“你不”!但是我们有个好消息。

systemd的理念是重新加载是可选的,如果没有真正的重新加载功能,则应取消定义。我将“真正的重载功能”定义为不会杀死并重新启动服务或使服务更改其PID的重载。换句话说,systemd只想反映存在哪些功能。

相反,您应该使用systemctl reload-or-restartwhich来进行重新加载(如果存在),然后重新启动(如果不存在)。

从手册页...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

因此:(1)将ExecReload留为空白,(2)使用,systemctl reload-or-restart MYSERVICE以及(3)您应该都准备就绪。

如果您确实尝试使用ExecReload定义一种杀死和重新启动服务的方法,它将有一个新的PID,并且systemd会感到困惑。


3

systemd的理念是reload可选的,并且systemd的用户对于每项服务都应该知道应调用reload还是通过调用来伪造它restart

因此,您的问题的答案是:“它不起作用,也不应该。请在下一个更高层上解决此问题。”

换句话说,systemd希望您仅在基础服务支持真正的重载功能时才实现“ 重载 ” ...即,重载不会终止和重启服务,也不会使服务更改其PID。换句话说,systemd只想反映存在哪些功能。

您可能会问自己:但是,如果我可以通过允许ExecReload终止并重新启动服务来实现“伪”重装,会不会更容易?然后,我可以使用systemctl reload FOO所有服务,而不必记住哪些支持它,哪些不支持?

是的,这会更容易,但不会以系统的方式进行。Systemd希望调用者是知道reload该服务是否存在的事物。Systemd希望成为现有功能的通用接口,而不希望负责填补这些空白。

例如,puppet假设systemd驱动的服务没有服务,reload并且默认为终止并重新启动该进程。如果Service []类型添加了一种方法来指定存在重载,并且应在通知时使用它,则它将需要了解哪些服务具有或没有本机重载。Chef和所有其他系统也必须学习相同的东西,因为systemd希望在该层解决该问题。(MiniRant:用于启动进程systemd似乎是全知,全挂载,全命名空间自定义的“我在层上做的一切”。因此,我无法告诉您为什么它不这样做将此哲学扩展到重新加载。也许其中一位作者可以在这里发出声音。)


1
systemctl reload-or-restart,它将在支持服务的情况下重新加载该服务,如果不支持,则将其重新启动。不知道为什么木偶做这个假设。
迈克尔·汉普顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.