Python 守护进程和 systemd 服务 [英] Python daemon and systemd service

查看:107
本文介绍了Python 守护进程和 systemd 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 Python 脚本作为守护进程.我正在尝试创建 systemd 脚本以便能够在启动期间启动此脚本.

I have a simple Python script working as a daemon. I am trying to create systemd script to be able to start this script during startup.

当前的 systemd 脚本:

Current systemd script:

[Unit]
Description=Text
After=syslog.target

[Service]
Type=forking
User=node
Group=node
WorkingDirectory=/home/node/Node/
PIDFile=/var/run/zebra.pid
ExecStart=/home/node/Node/node.py

[Install]
WantedBy=multi-user.target

node.py:

if __name__ == '__main__':
    with daemon.DaemonContext():
        check = Node()
        check.run()

run 包含 while True 循环.

我尝试使用 systemctl start zebra-node.service 运行此服务.不幸的是,服务从未完成说明序列 - 我必须按 Ctrl+C.脚本正在运行,但状态正在激活,一段时间后它更改为停用.现在我正在使用 python-daemon(但在我尝试不使用它之前,症状是相似的).

I try to run this service with systemctl start zebra-node.service. Unfortunately service never finished stating sequence - I have to press Ctrl+C. Script is running, but status is activating and after a while it change to deactivating. Now I am using python-daemon (but before I tried without it and the symptoms were similar).

我应该为我的脚本实现一些额外的功能还是 systemd 文件不正确?

Should I implement some additional features to my script or is systemd file incorrect?

推荐答案

它没有完成启动顺序的原因是,对于 Type forking 你的启动过程预计会 fork 并退出 (请参阅 $ man systemd.service - 搜索分叉).

The reason, it does not complete the startup sequence is, that for Type forking your startup process is expected to fork and exit (see $ man systemd.service - search for forking).

一种选择是少做.使用 systemd,通常不需要创建守护进程,您可以直接运行代码,无需守护进程.

One option is to do less. With systemd, there is often no need to create daemons and you may directly run the code without daemonizing.

#!/usr/bin/python -u
from somewhere import Node
check = Node()
check.run()

这允许使用称为 simple 的更简单的服务类型,因此您的单元文件将如下所示.

This allows using simpler Type of service called simple, so your unit file would look like.

[Unit]
Description=Simplified simple zebra service
After=syslog.target

[Service]
Type=simple
User=node
Group=node
WorkingDirectory=/home/node/Node/
ExecStart=/home/node/Node/node.py
StandardOutput=syslog
StandardError=syslog

[Install]
WantedBy=multi-user.target

请注意,python shebang 中的 -u 不是必需的,但是如果您将某些内容打印到 stdout 或 stderr,-u 可以确保,有没有输出缓冲,打印的行将立即被 systemd 捕获并记录在日志中.没有它,它会出现一些延迟.

Note, that the -u in python shebang is not necessary, but in case you print something out to the stdout or stderr, the -u makes sure, there is no output buffering in place and printed lines will be immediately caught by systemd and recorded in journal. Without it, it would appear with some delay.

为此,我将 StandardOutput=syslogStandardError=syslog 行添加到单元文件中.如果您不关心日记中的打印输出,请不要关心这些行(它们不必存在).

For this purpose I added into unit file the lines StandardOutput=syslog and StandardError=syslog. If you do not care about printed output in your journal, do not care about these lines (they do not have to be present).

虽然您的问题的标题明确询问了守护进程,但我想问题的核心是如何让我的服务运行",而使用主进程似乎更简单(您没有根本不必关心守护进程),它可以被认为是对您问题的回答.

While the title of your question explicitly asks about daemonizing, I guess, the core of the question is "how to make my service running" and while using main process seems much simpler (you do not have to care about daemons at all), it could be considered answer to your question.

我认为,很多人使用守护进程只是因为每个人都这样做".使用 systemd,守护进程的原因通常已经过时.使用守护进程可能有一些原因,但现在这种情况很少见.

I think, that many people use daemonizing just because "everybody does it". With systemd the reasons for daemonizing are often obsolete. There might be some reasons to use daemonization, but it will be rare case now.

python -p 修正为正确的 python -u.谢谢kmftzg

fixed python -p to proper python -u. thanks kmftzg

这篇关于Python 守护进程和 systemd 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆