为什么我的 Systemd 单元已加载,但处于非活动状态(死机)?

为什么我的 Systemd 单元已加载,但处于非活动状态(死机)?

我正在尝试设置石墨在我的服务器上。我可以毫无问题地启动 Carbon Cache 守护进程sudo /opt/graphite/bin/carbon-cache.py start,但我很难将它作为 Systemd 单元运行。

这是我的服务文件中的内容graphite.service

[Unit]
Description=Carbon for Graphite

[Service]
ExecStart=/opt/graphite/bin/carbon-cache.py start

[Install]
WantedBy=multi-user.target

但是当我启动设备时,我得到以下状态:

$ systemctl status graphite.service            
* graphite.service - Carbon for Graphite
   Loaded: loaded (/etc/systemd/system/graphite.service; enabled)
   Active: inactive (dead) since Fri 2014-06-13 18:44:11 UTC; 2s ago
  Process: 4525 ExecStart=/opt/graphite/bin/carbon-cache.py start (code=exited, status=0/SUCCESS)
 Main PID: 4525 (code=exited, status=0/SUCCESS)

Jun 13 18:44:11 MEADOW systemd[1]: Started Carbon for Graphite.

Journalctl 不会产生更多信息。

我应该如何解释和调试状态为“非活动(死亡)...(代码=已退出,状态=0/成功)”的单元?我以前见过失败的单元,但是这个单元已成功加载但未运行,我不知道这意味着什么。

答案1

根据 jasonwryan 的评论,虽然默认值Type=simple适用于许多 Systemd 服务文件,但当脚本启动另一个进程并完成时,它不起作用ExecStart,就像石墨的 Carbon-cache.py 的情况一样。在这些情况下,您需要Type=forking[Service]部分中显式指定,以便 Systemd 知道查看生成的进程而不是初始进程。

正如中所解释的man systemd.service

如果设置为 forking,则预计使用 ExecStart= 配置的进程将调用 fork() 作为其启动的一部分。当启动完成并且所有通信通道都建立后,父进程预计将退出。子进程继续作为主守护进程运行。这是传统 UNIX 守护程序的行为。如果使用此设置,建议同时使用 PIDFile= 选项,以便 systemd 可以识别守护进程的主进程。一旦父进程退出,systemd 将继续启动后续单元。

石墨具体答案

虽然上面解决了我的 Systemd 问题,但我很快就遇到了石墨特定的问题(使用 Twisted)并最终回到了默认的Type.

石墨 < 0.9.12

在以前的 Graphite 版本中,只能通过使用以下--debug选项来避免分叉:

[Service]
ExecStart=/opt/graphite/bin/carbon-cache.py --debug start

石墨 >= 0.9.13

这个拉取请求--no-daemon合并了一个选项:

[Service]
ExecStart=/opt/graphite/bin/carbon-cache.py --no-daemon start

相关内容