我计划为使用systemd
.我希望能够stop
使用start
每个客户实例systemd
,并将整个客户实例集合视为可以一起停止和启动的单个服务。
systemd
似乎提供了我需要使用的构建块PartOf
和模板单元文件,但是当我停止父服务时,子客户服务并未停止。我怎样才能使这个与 systemd 一起工作?这是我到目前为止所拥有的。
父单元文件,app.service
:
[Unit]
Description=App Web Service
[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal
名为 的单元模板文件[email protected]
,用于创建客户实例:
[Unit]
Description=%I Instance of App Web Service
[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal
我的app-poc.sh
脚本(仅循环打印到日志文件的概念证明):
#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
echo "The App PoC loop for $@"
sleep 2;
done
为了证明概念,我将 systemd 单元文件放在~/.config/systemd/user
.
然后,我启动父级和基于模板的实例(之后systemctl --user daemon-reload
):
systemctl --user start app
systemctl --user start [email protected]
从使用中journalctl -f
我可以看到两者都已启动并且客户实例继续运行。现在我预计关闭父母会阻止孩子(因为我用过PartOf
),但事实并非如此。此外,启动父进程也没有按预期启动子进程。
systemctl --user stop app
谢谢!
(我使用的是 Ubuntu 16.04 和 systemd 229)。
答案1
我了解到这就是 systemd“目标单元”的用途。通过使用目标单元,我可以获得我想要的好处,而无需创建[Service]
上面的假部分。一个工作示例“目标单元”文件如下所示:
# named like app.target
[Unit]
Description=App Web Service
# This collection of apps should be started at boot time.
[Install]
WantedBy=multi-user.target
然后,每个客户实例都应包含PartOf
在该[Unit]
部分中(如 @meuh 所指出的),并且还应该有一个[Install]
部分,以便enable
和disable
能够处理特定的服务:
# In a file name like [email protected]
[Unit]
Description=%I Instance of App Web Service
PartOf=app.target
[Service]
ExecStart=/home/mark/bin/app-poc.sh %i
Restart=on-failure
StandardOutput=journal
# When the service runs globally, make it run as a particular user for added security
#User=myapp
#Group=myapp
# When systemctl enable is used, make this start when the App service starts
[Install]
WantedBy=app.target
要启动客户实例并使其在目标启动时启动,请使用以下一次性启用命令:
systemctl enable app
现在,我可以对特定实例使用 和 ,或者我可以使用和stop
一起停止所有应用程序。start
app@customer
start app
stop app
答案2
你需要移动线路
PartOf=app.service
出入[Service]
该[Unit]
部分,并添加到要启动的客户列表[Unit]
中,例如app.service
[email protected] [email protected]
或者正如 Sourcejedi 在评论中所说,Requires=
同样的事情。您可以保留PartOf
上面列表中没有的手动启动的停止服务,例如.systemctl --user start [email protected]