如何解决管道中的python进程返回异常后,Systemd单元未失败
我们有这个 systemd 单元,它在其 ExecStart=
指令中启动两个管道 python 进程。该单元的类型为:oneshot
,并且当第一个 Python 进程以某种方式引发异常时,该单元将返回到 inactive
状态。
下面是我们的单位。它没有:[Install]
部分,因为我们使用计时器触发它,或者手动使用:systemctl start my-unit.service
:
[Unit]
Description=Connector
Documentation=Docs
StartLimitInterval=600
StartLimitBurst=3
[Service]
Type=oneshot
User=user
Group=group
WorkingDirectory=/home/user/dir
ExecStartPre=bash -c 'echo "Pre"'
ExecStart=bash -c 'python_1 | python_2'
ExecStartPost=bash -c 'echo "Post"'
KillMode=control-group
KillSignal=SIGTERM
StandardOutput=append:/home/user/dir/out.log
StandardError=append:/home/user/dir/err.log
TimeoutSec=21600
Restart=on-failure
RestartSec=5
RemainAfterExit=false
来自文档 systemd 不支持管道,这就是为什么我们一直在运行包含在 bash -c '...'
命令中的整个事情。
通过查看日志,我知道第一个 python 进程引发了异常:/home/user/dir/err.log
。这是第一个进程引发异常后单元的状态:
● my-unit.service - Connector
Loaded: loaded (/etc/systemd/system/my-unit.service; static; vendor preset: enabled)
Active: inactive (dead) since Tue 2021-05-11 14:48:24 UTC; 12s ago
TriggeredBy: ● my-unit.timer
Process: 108838 ExecStartPre=/usr/bin/bash -c echo "Pre" (code=exited,status=0/SUCCESS)
Process: 108839 ExecStart=/usr/bin/bash -c p1 | p2 (code=exited,status=0/SUCCESS)
Process: 108973 ExecStartPost=/usr/bin/bash -c echo "Post" (code=exited,status=0/SUCCESS)
Main PID: 108839 (code=exited,status=0/SUCCESS)
May 11 14:48:21 ip-10-11-0-81 systemd[1]: Starting Connector...
May 11 14:48:24 ip-10-11-0-81 systemd[1]: connector-mavenlink.service: Succeeded.
May 11 14:48:24 ip-10-11-0-81 systemd[1]: Finished Connector mavenlink.
我们通常对这个单元很满意,这是它第一次出现故障,但我们真的希望它进入 Failed
状态,因为我们有可观察性工具来监控它。
有什么想法吗?
谢谢!
解决方法
所以我想我解决了我自己的问题,所以我会把它写在这里,可能在我关闭它之前把它留在这里一段时间。它确实感觉有点hacky。
status code
指令的 ExecStart=
被 systemd 认为是:0
这一事实让我想起了我们用来制作 bash 的 set -o pipefail
bash 标志脚本将管道错误理解为全局错误(措辞不佳,但我认为这是它的要点)
因此,我编辑了我们的单元,在 -o pipefail
命令中添加了 bash -c '...'
标志,如下所示:
[Unit]
Description=Connector
Documentation=Docs
StartLimitInterval=600
StartLimitBurst=3
[Service]
Type=oneshot
User=user
Group=group
WorkingDirectory=/home/user/dir
ExecStartPre=bash -c 'echo "Pre"'
ExecStart=bash -c 'set -o pipefail && python_1 | python_2'
ExecStartPost=bash -c 'echo "Post"'
KillMode=control-group
KillSignal=SIGTERM
StandardOutput=append:/home/user/dir/out.log
StandardError=append:/home/user/dir/err.log
TimeoutSec=21600
Restart=on-failure
RestartSec=5
RemainAfterExit=false
... 这似乎有效:现在当第一个 python 进程引发异常时,我们的单元被发送到:failed
状态(在我们配置后重新启动几次之后)。以下是更新后的 failed
状态:
● my-unit.service - Connector
Loaded: loaded (/etc/systemd/system/my-unit.service; static; vendor preset: enabled)
Active: failed (Result: exit-code) since Tue 2021-05-11 15:01:28 UTC; 1s ago
TriggeredBy: ● my-unit.timer
Docs: Docs
Process: 109454 ExecStartPre=/usr/bin/bash -c echo "Pre" (code=exited,status=0/SUCCESS)
Process: 109463 ExecStart=/usr/bin/bash -c set -o pipefail && p1 | p2 (code=exited,status=1/FAILURE)
Main PID: 109463 (code=exited,status=1/FAILURE)
May 11 15:01:28 ip-10-11-0-81 systemd[1]: my-unit.service: Scheduled restart job,restart counter is at 3.
May 11 15:01:28 ip-10-11-0-81 systemd[1]: Stopped Connector.
May 11 15:01:28 ip-10-11-0-81 systemd[1]: my-unit.service: Start request repeated too quickly.
May 11 15:01:28 ip-10-11-0-81 systemd[1]: my-unit.service: Failed with result 'exit-code'.
May 11 15:01:28 ip-10-11-0-81 systemd[1]: Failed to start Connector.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。