当我在没有 systemd 的情况下启动它时,systemd 服务会使用 100% 的 CPU

当我在没有 systemd 的情况下启动它时,systemd 服务会使用 100% 的 CPU

我正在使用带有最新更新的 Debian Jessie。我创建了一个 systemd 服务来在服务器启动时运行脚本。这是它的配置:

[Unit]
Description=(my description)

[Service]
ExecStart=/usr/bin/bot
Restart=restart-always

[Install]
WantedBy=multi-user.target

/usr/bin/bot是运行 Mono 可执行文件的脚本。它包括:

#!/bin/bash
(cd /path/to/my/executable && mono bot.exe)

(我在这里替换了路径,但我的脚本上的路径是正确的。)

/usr/bin/bot当我正常运行脚本(仅/usr/bin/bot在我的终端上)时,它按预期工作。top报告它使用了 0 到 20% 的 CPU,这是正常的。但是当我用 启动它时service bot starttop说它总是使用至少 100% 的 CPU。

在这两种情况下都bot按预期工作。

什么可以解释 CPU 使用率如此大的差异?

谢谢。

答案1

问题不在于systemd。

Systemd 在没有标准输入的情况下运行进程(=/dev/null)。所有系统调用read()都会立即完成(使用正常的标准输入,read()会被阻止,直到新数据到达)。一般来说,read()在未完成的循环中调用会产生巨大的 CPU 使用率。要确认这一点,请尝试使用 附加到正在运行的进程strace -p <pid>

进程必须适应在没有标准输入的情况下运行或使用一些包装器,例如建议的screen命令或nohup

答案2

bot我通过将我的放在a 下来“修复它” screen,如下所示:

[Unit]
Description=(my description)

[Service]
RemainAfterExit=yes
ExecStart=/usr/bin/screen -dmS bot /usr/bin/bot
Restart=restart-always

[Install]
WantedBy=multi-user.target

我不知道为什么将我的进程放在屏幕上可以修复其高 CPU 使用率,但是嘿,它确实有效。

答案3

根据 @niziak 的解决方案,输入被阻塞。就我而言,通过添加StandardInput=tty到[服务]解决了它。我已经将输出重定向到 /dev/tty12 上的(未使用的)控制台。

我的[服务]部分:

[Service]
ExecStart=/usr/local/bin/vtclock -1  -c| -f /tmp/ntpstatus
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=simple
User=vtclock
StandardInput=tty
StandardOutput=tty
StandardError=null
TTYPath=/dev/tty12 

(操作系统 = Ubuntu 16.04.3 LTS,我第一次尝试 systemd 服务)

答案4

如果您已经在 C# / .NET Core 中开发了控制台应用程序,请不要使用以下方法保持控制台运行:

Console.Read();

因为当您在 Linux 上将应用程序作为 systemd 服务运行时,这将导致 CPU 使用率 100%。

而是使用:

while (true) { Console.ReadKey(); }

我有同样的问题。

相关内容