systemd:如果任何分叉进程被终止,请重新启动服务

systemd:如果任何分叉进程被终止,请重新启动服务

如果任何派生进程被终止,是否有任何方法可以自动重新启动 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_ctmatopens 127.0.0.1:7035,systemd 可以监控这个端口并在关闭时重新启动服务吗?


PS1:我愿意不是可以控制start-agshut-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-agand 的包装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_ENABLEDY。在我的测试中,这使得进程p_ctmag能够监视p_ctmat进程,必要时将重新启动它。该p_ctmatw进程是该进程的子进程p_ctmat,它将p_ctmatw根据需要重新启动。

从那里开始,您就可以:

  • p_ctmag将由 重新启动systemd,就像现在一样
  • p_ctmat将由p_ctmag(with WATCHDOG_ENABLED Y)重新启动
  • p_ctmatw将由 重新启动p_ctmat,就像现在一样

相关内容