【问题标题】:Systemctl blocking when starting my deamon启动我的守护程序时 Systemctl 阻塞
【发布时间】:2019-02-13 13:51:48
【问题描述】:

我用 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: 失败,结果为“超时”。

这是怎么回事?

【问题讨论】:

  • 也许使用one-shot 比使用forking 更容易并且不要分叉?
  • 不,不是因为我的脚本已经是一个守护进程
  • systemd 和其他服务监控工具,确实更喜欢不分叉的守护进程。如果您更改您的守护程序或向其添加一个标志,以便它不会从第一个进程分叉,那么您可以将其设置为 Type=simple,它不需要 PID 文件或任何东西。

标签: python linux daemon systemd


【解决方案1】:

问题是您的服务自己创建了守护进程,而 systemd 对此一无所知。它只是一个简单的程序,在 systemd 的少量时间后运行和退出。而不是forking,你想使用simple

Type=simple

Systemd 仍将作为守护进程跟踪您的进程,因为它知道它的 pid:

systemctl status 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 守护进程会分叉,因为当我执行 ./daemon start 时它会启动并返回,但守护进程仍保留在内存中。那么forking守护进程是什么意思呢?
  • 据我了解,它不会分叉。 daemonocle 只是创建一个子进程并将其与主进程分离。如果我错了,请纠正我,我没有太多时间阅读文档:(
  • 你可能比我更了解这一点。我不能说子进程和分叉之间的区别:(
  • here 我可以阅读而不是os.fork 创建一个子进程:( 现在我很困惑
  • 是的,但是 fork 并不是唯一一种创建子进程的方法。 exec 也会创建一个子进程。
猜你喜欢
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 2018-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-05
  • 2017-10-25
相关资源
最近更新 更多