Systemd:监督进程XXXX,它不是我们的孩子。我们很可能不会注意到它何时退出

kto*_*paz 9 linux bash systemd systemctl centos7

我创建了一个自定义服务文件,如下所示:

cat /etc/systemd/system/aaa.service

[Unit]
Description=aaa main application
After=syslog.target network-online.target

[Service]
Type=forking
PIDFile=/usr/local/aaa_path/aaa/aaa.pid
WorkingDirectory=/usr/local/aaa_path/aaa/
ExecStart=/usr/local/aaa_path/aaa/run_aaa.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

检查状态时:

systemctl status aaa
Run Code Online (Sandbox Code Playgroud)

一切看起来都不错,除了:

... systemd[1]: aaa.service: Supervising process 18285 which is not our child. We'll most likely not notice when it exits.
Run Code Online (Sandbox Code Playgroud)

想知道为什么会显示此消息以及是否需要关注?

我的 ExecStart 是一个名为 run_aaa.sh 的 bash 脚本;它所做的是准备一些环境变量,运行一些必需的维护脚本,最后在后台运行带有一些动态命令行选项的 aaa 二进制文件(作为守护进程) - 然后退出(run_aaa.sh 脚本退出,aaa 守护进程) binary 在后台继续运行,并维护自己的 pid 文件,systemd 知道)

我知道 systemd 正在运行 run_aaa.sh 并期望它分叉(因为我指定了 type=forking)并且它实际上通过在后台运行“aaa”二进制守护程序并随后退出来“分叉”。另外,我确实指定了 PIDFile 路径,并且我的 aaa 二进制文件按原样维护了这个 PIDFile,那么为什么 systemd 会抱怨它可能无法监督我的守护进程?

有没有更好的方法来为这个用例配置服务?(我必须使用 run_aaa.sh 脚本来执行我的二进制文件)

sek*_*ett 2

如果您只需要运行一次 shell 脚本,那么只需添加ExecStartPre=/path/to/script并运行您的守护进程ExecStart=/path/to/daemon。该脚本不会在重新启动时运行,也许这不是您所需要的。

如果您还需要在重新启动时运行脚本,请Type=simple从 shell 脚本设置并在前台模式下运行守护进程,这样脚本就不会退出。但您仍然收到该消息,并且停止/重新启动操作已等待 30 秒State 'stop-sigterm' timed out. Killing,这非常令人不快。如果您随后添加ExecStop=/bin/kill $MAINPID,超时问题就会消失。不要删除PIDFile. 您仍然会看到该消息,但每个操作启动/停止/重新启动/状态都能正常工作。也许还有另一种更好的方法可以达到同样的目的。至少这对我有用,并且可以安全地忽略该消息。当守护进程退出时,shell 脚本也会退出,因此 systemd 会知道这一点。