如果任何派生进程被终止,是否有任何方法可以自动重新启动 systemd 服务?
为 Control-M 创建 systemd 单元文件后
[Unit]
After = network-online.target
After = remote-fs.target
Description = Control-M agent
Wants = network-online.target
[Service]
ExecStart = /opt/ctmagent/ctm/scripts/start-ag -u ctmagent -p ALL
ExecStop = /opt/ctmagent/ctm/scripts/shut-ag -u ctmagent -p ALL
Restart = always
RestartSec = 5
TimeoutSec = 5min
Type = forking
[Install]
WantedBy = multi-user.target
我注意到它分叉了 3 个不同的进程
# systemctl status ctmag.service
CGroup: /system.slice/ctmag.service
├─129041 /opt/ctmagent/ctm/exe/p_ctmag
├─129089 /opt/ctmagent/ctm/exe/p_ctmat
└─129091 /opt/ctmagent/ctm/exe/p_ctmatw -ATW_NAME ATW000
如果我杀了p_ctmag
,systemd 会重新启动一切,但是,如果我杀了p_ctmat
它,则不会
或者,既然p_ctmat
opens 127.0.0.1:7035
,systemd 可以监控这个端口并在关闭时重新启动服务吗?
PS1:我愿意不是可以控制start-ag
和shut-ag
,所以如果控制组中的进程之一失败,则 Systemd 重新启动服务在这里没有帮助。
PS2:另外,我无法添加另一个脚本“层”,将脚本包装在另一个脚本“层”中。需要纯 systemd 单元文件解决方案。
答案1
您遇到的麻烦是 BMC 尚未为 Control-M/Agent 构建本机 systemd 服务文件。这9.0.18.200版本安装指南)(需要登录),对于 systemd-systems 指示您使用具有此模板的服务文件:
[Unit]
Description=Control-M Agent
[Service]
Type=forking
RemainAfterExit=yes
ExecStart=[agent_home_dir]/ctm/scripts/rc.agent_user start
ExecStop=[agent_home_dir]/ctm/scripts/rc.agent_user stop
[Install]
WantedBy=multi-user.target
...其中 Exec 行只是start-ag
and 的包装shut-ag
,这就是您正在使用的。问题归结为 systemd 被告知这是一种forking
服务类型,而实际上“服务”(启动脚本)启动了多个进程。当 systemd 在初始脚本之后看到第一个子进程时,它认为(分叉)服务成功。p_ctmag
正如您所看到的,该过程最终是。输出systemctl status
很清楚:
Process: 6519 ExecStart=/opt/ctmagent/ctm/scripts/start-ag -u ctmagent -p ALL (code=exited, status=0/SUCCESS)
...其中 pid 6519 是start-ag
脚本,该脚本已退出。接下来是您看到的其余控制组进程。
我还想在这里指出系统文档说:
如果使用此设置,建议同时使用PIDFile=选项,以便systemd能够可靠地识别服务的主进程。
...建议的 BMC 服务文件不包含其中,尽管有$CONTROLM/pid/
;下所有三个进程的 PID 文件虽然他们不是真实的PID 文件,因为这些文件是命名的为 pid 而不是 pid 是它们的内容。
这就是 systemd 不重新启动该p_ctmat
进程的原因。
如果没有重写一千多行供应商脚本来将进程拆分为单独控制的进程(包括这些脚本设置的两个环境变量)或等待 BMC 提供有用的 systemd 脚本,我的建议是更改您的代理配置以将参数设置WATCHDOG_ENABLED
为Y
。在我的测试中,这使得进程p_ctmag
能够监视p_ctmat
进程,必要时将重新启动它。该p_ctmatw
进程是该进程的子进程p_ctmat
,它将p_ctmatw
根据需要重新启动。
从那里开始,您就可以:
p_ctmag
将由 重新启动systemd
,就像现在一样p_ctmat
将由p_ctmag
(withWATCHDOG_ENABLED Y
)重新启动p_ctmatw
将由 重新启动p_ctmat
,就像现在一样