我正在使用 systemd 单元文件来控制在服务器上运行的 python 进程(使用 systemd v247)。
此进程必须在退出后 60 秒重新启动,无论是失败还是成功,除非它在 600 秒内失败 5 次。
该单元文件链接另一个服务,以便通过电子邮件通知故障。
/etc/systemd/system/python-test.service
[Unit]
After=network.target
OnFailure=mailer@%n.service
[Service]
Type=simple
ExecStart=/home/debian/tmp.py
# Any exit status different than 0 is considered as an error
SuccessExitStatus=0
StandardOutput=append:/var/log/python-test.log
StandardError=append:/var/log/python-test.log
# Always restart service 60sec after exit
Restart=always
RestartSec=60
# Stop restarting service after 5 consecutive fail in 600sec interval
StartLimitInterval=600
StartLimitBurst=5
[Install]
WantedBy=multi-user.target
/etc/systemd/system/[email protected]
[Unit]
After=network.target
[Service]
Type=oneshot
ExecStart=/home/debian/mailer.py --to "[email protected]" --subject "Systemd service %I failed" --message "A systemd service failed %I on %H"
[Install]
WantedBy=multi-user.target
在基本测试期间,触发OnFailure
工作得很好。但是,当我将以下部分添加到单元文件中时,OnFailure
仅在连续 5 次失败时触发。
StartLimitInterval=600
StartLimitBurst=5
这不是我想要的行为,因为我希望每次进程失败时都能收到通知,即使尚未达到突发限制。
检查进程状态时,未达到突发限制时输出不同
● python-test.service
Loaded: loaded (/etc/systemd/system/python-test.service; disabled; vendor preset: enabled)
Active: activating (auto-restart) (Result: exit-code) since Thu 2022-12-22 19:51:23 UTC; 2s ago
Process: 1421600 ExecStart=/home/debian/tmp.py (code=exited, status=1/FAILURE)
Main PID: 1421600 (code=exited, status=1/FAILURE)
CPU: 31ms
Dec 22 19:51:23 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.
比当它是
● python-test.service
Loaded: loaded (/etc/systemd/system/python-test.service; disabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Thu 2022-12-22 19:52:02 UTC; 24s ago
Process: 1421609 ExecStart=/home/debian/tmp.py (code=exited, status=1/FAILURE)
Main PID: 1421609 (code=exited, status=1/FAILURE)
CPU: 31ms
Dec 22 19:51:56 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Scheduled restart job, restart counter is at 5.
Dec 22 19:52:02 test-vps systemd[1]: Stopped python-test.service.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Start request repeated too quickly.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.
Dec 22 19:52:02 test-vps systemd[1]: Failed to start python-test.service.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Triggering OnFailure= dependencies.
我找不到任何解释如何OnFailure
在单元文件中修改触发的内容。
有没有办法在每次进程失败时通知邮件并仍然保持突发限制?
为了根据需要使用系统服务,您应该做几件事(更改在/etc/systemd/system/python-test.service上)。
Restart=always
_Restart=on-failure
StartLimitInterval=600
,StartLimitBurst=5
似乎还得到支持。但是你应该把它们放在[Unit]
. 如果您放置StartLimitInterval
在[Unit]
您可以将其重命名为StartLimitIntervalSec
(改为man systemd.unit
使用StartLimitIntervalSec
)。RemainAfterExit=no
到[Service]
部分。[Service]
:TimeoutStopSec=infinity
EXIT_STATUS
来确定脚本是否成功退出。OnFailure=mailer@%n.service
_OnFailure=mailer@%N.service
两者的区别是using%N
会去掉后缀。atd
(sudo systemctl start atd.service
) 以便能够使用at
命令。或者,如果您不想使用,at
则可以编写另一个 systemd 服务来重新启动该服务。(在这个例子中,我使用了relaunch.service
)sleep
在和上使用相同的值RestartSec
。在你的情况下,因为RestartSec
在60
这一行中 sleep60
也必须有:ExecStart
和ExecStopPost=
获取主进程的ExitStatus/home/debian/tmp.py
:。不要使用ExecStop
, 来自man systemd.service
:服务/etc/systemd/system/python-test.service应该是:
/home/debian/bin/checkSuccess应该有这个:
解决方案 1:使用
at
命令:解决方案 2:使用另一个 systemd 服务:
relaunch.service
应该有:systemd 服务设置的
"$EXIT_STATUS"
变量由 的退出状态决定/home/debian/tmp.py
。${1}
代表单元的名称: 并python-test
传递给行中的脚本/home/debian/bin/checkSuccess "%N"
。笔记:
'echo The Service %n has exited with values: $$EXIT_STATUS,$$SERVICE_RESULT,$$EXIT_CODE'
您可以使用以下方式实时检查日志:relaunch.service
如果你想停止你的主要服务时使用解决方案 2 ( with ),你应该运行: