我正在使用带有最新更新的 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 start
,top
说它总是使用至少 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(); }
我有同样的问题。