启动我的恶魔时 Systemctl 阻塞
Systemctl blocking when starting my deamon
我在 Python 中编写了一个小守护进程:
#!/usr/bin/python3
import time
import click
import daemonocle
from daemonocle.cli import DaemonCLI
@click.command(cls=DaemonCLI, daemon_params={'pidfile': '/var/run/daemon.pid'})
def main():
while True:
time.sleep(3)
if __name__ == '__main__':
main()
它的效果很好。如果我执行以下操作,我将获得良好的退出状态 0
$ sudo ./daemon start
Starting daemon ... OK
$ echo $?
0
然后我写了一个systemd
服务文件:
[Unit]
SourcePath=/home/pi/daemon/daemon
Description=My First Daemon
Before=multi-user.target
After=mosquitto.target
[Service]
Type=forking
PIDFile=/var/run/daemon.pid
Restart=no
ExecStart=/home/pi/daemon/daemon start
ExecStop=/home/pi/daemon/daemon stop
ExecReload=/home/pi/daemon/daemon reload
如果我尝试使用 systemctl
运行 我的守护程序,命令仍然阻塞:
$ sudo systemctl start daemon
^C
$ sudo systemctl status daemon
? daemon.service - XEMWAY Demo Service
Loaded: loaded (/home/pi/daemon/daemon; static; vendor preset: enabled)
Active: activating (start) since Wed 2019-02-13 13:47:40 GMT; 12s ago
Process: 13044 ExecStop=/home/pi/daemon/daemon stop (code=exited, status=0/SUCCESS)
Main PID: 12304 (code=exited, status=143); Control PID: 13079 (daemon)
CGroup: /system.slice/daemon.service
+-13079 /usr/bin/python3 /home/pi/daemon/daemon start
+-13081 /usr/bin/python3 /home/pi/daemon/daemon start
一分钟后 systemd
说:
2 月 13 日 13:49:10 raspberrypi systemd[1]:daemon.service:设备进入故障状态。
2 月 13 日 13:49:10 raspberrypi systemd[1]:daemon.service:结果失败 'timeout'。
这有什么问题?
问题是您的服务自己创建了守护进程,而 systemd 并不知道。它只是一个简单的程序,在 systemd 的少量时间后运行并退出。而不是 forking
你想使用 simple
:
Type=simple
Systemd 仍然会作为守护进程跟踪您的进程,因为它知道它的 pid:
systemctl 状态 test2.service
* test2.service - My First Daemon
Loaded: loaded (/tmp/a.py; static; vendor preset: disabled)
Active: active (running) since Wed 2019-02-13 16:06:27 EET; 5s ago
Main PID: 18104 (python)
Tasks: 2 (limit: 4915)
Memory: 10.1M
CGroup: /system.slice/test2.service
|-18104 /usr/bin/python /tmp/a.py start
`-18115 /usr/bin/python /tmp/a.py start
我在 Python 中编写了一个小守护进程:
#!/usr/bin/python3
import time
import click
import daemonocle
from daemonocle.cli import DaemonCLI
@click.command(cls=DaemonCLI, daemon_params={'pidfile': '/var/run/daemon.pid'})
def main():
while True:
time.sleep(3)
if __name__ == '__main__':
main()
它的效果很好。如果我执行以下操作,我将获得良好的退出状态 0
$ sudo ./daemon start
Starting daemon ... OK
$ echo $?
0
然后我写了一个systemd
服务文件:
[Unit]
SourcePath=/home/pi/daemon/daemon
Description=My First Daemon
Before=multi-user.target
After=mosquitto.target
[Service]
Type=forking
PIDFile=/var/run/daemon.pid
Restart=no
ExecStart=/home/pi/daemon/daemon start
ExecStop=/home/pi/daemon/daemon stop
ExecReload=/home/pi/daemon/daemon reload
如果我尝试使用 systemctl
运行 我的守护程序,命令仍然阻塞:
$ sudo systemctl start daemon
^C
$ sudo systemctl status daemon
? daemon.service - XEMWAY Demo Service
Loaded: loaded (/home/pi/daemon/daemon; static; vendor preset: enabled)
Active: activating (start) since Wed 2019-02-13 13:47:40 GMT; 12s ago
Process: 13044 ExecStop=/home/pi/daemon/daemon stop (code=exited, status=0/SUCCESS)
Main PID: 12304 (code=exited, status=143); Control PID: 13079 (daemon)
CGroup: /system.slice/daemon.service
+-13079 /usr/bin/python3 /home/pi/daemon/daemon start
+-13081 /usr/bin/python3 /home/pi/daemon/daemon start
一分钟后 systemd
说:
2 月 13 日 13:49:10 raspberrypi systemd[1]:daemon.service:设备进入故障状态。 2 月 13 日 13:49:10 raspberrypi systemd[1]:daemon.service:结果失败 'timeout'。
这有什么问题?
问题是您的服务自己创建了守护进程,而 systemd 并不知道。它只是一个简单的程序,在 systemd 的少量时间后运行并退出。而不是 forking
你想使用 simple
:
Type=simple
Systemd 仍然会作为守护进程跟踪您的进程,因为它知道它的 pid:
systemctl 状态 test2.service
* test2.service - My First Daemon
Loaded: loaded (/tmp/a.py; static; vendor preset: disabled)
Active: active (running) since Wed 2019-02-13 16:06:27 EET; 5s ago
Main PID: 18104 (python)
Tasks: 2 (limit: 4915)
Memory: 10.1M
CGroup: /system.slice/test2.service
|-18104 /usr/bin/python /tmp/a.py start
`-18115 /usr/bin/python /tmp/a.py start