我们有一个调用多个 tomcat 实例的 systemd 服务。
[Unit]
Description=Tomcat Services
After=network.target multi-user.target
[Service]
Type=forking
ExecStart=/users/mwe/scripts/appstart.sh
ExecStop=/users/mwe/scripts/appstop.sh
Restart=on-abort
User=webapp
Group=webgrp
[Install]
WantedBy=multi-user.target
我们修补/重新启动了系统,服务按预期启动。
Jul 10 20:38:02 a8cc08d appstart.sh[5989]: [AA00001654][AA00001654_PRD] - Remove all log files older than 90 days ...
Jul 10 20:38:03 a8cc08d appstart.sh[5989]: [etp][ciiprod] - Remove all log files older than 90 days ...
Jul 10 20:38:03 a8cc08d appstart.sh[5989]: [etp][ciiprod] -----------------------------
...
Jul 10 20:38:08 a8cc08d systemd[1]: Started Tomcat Services.
然而,大约 22.5 小时后,ExecStop 脚本显然是由 systemd 运行的。
Jul 11 19:00:07 a8cc08d appstop.sh[29451]: [etp][ciiprod] -----------------------------
Jul 11 19:00:48 a8cc08d appstop.sh[29451]: [2.0K blob data]
Jul 11 19:00:48 a8cc08d appstop.sh[29451]: Completed execution of . / tcruntime-ctl.sh
Jul 11 19:00:48 a8cc08d appstop.sh[29451]: [oasys][ciiprod] -----------------------------
Jul 11 19:00:48 a8cc08d appstop.sh[29451]: tcServer is not running for environment: ciiprod.
Jul 11 19:00:48 a8cc08d appstop.sh[29451]: Completed execution of . / tcruntime-ctl.sh
Jul 11 19:00:48 a8cc08d appstop.sh[29451]: [report][ciiprod] -----------------------------
此时没有用户登录,没有配置 cron 作业,没有 autosys 作业等。如果发生了这种情况,我们不明白为什么 systemd 会自行调用 ExecStop 脚本。我读到如果服务“崩溃”,ExecStop 就会运行,但它如何确定这一点,systemd 不会在日志中报告服务故障吗?我们测试了使用每个终止信号终止应用程序进程,但无法复制此行为。它要么重新启动(Restart=on-abort),要么只报告失败(干净地终止时),并始终将失败记录在日志中。我们知道“systemctl stop”没有运行,因为这会将“Stopping”和服务描述插入到日志中,但事实并非如此。出现的只是 appstop.sh 脚本(ExecStop)的输出。
RHEL 7.9。我们有一个与 Red Hat 合作的案例,但我不太相信他们会深入研究 systemd 并找到答案。
更新:更多发现,有一个 Autosys 作业会关闭并重新启动其中一个 tomcat 实例,并且时间与 appstop.sh 运行时相对应。当一个实例在 systemd 之外停止时,systemd 是否可能认为整个 cgroup 不健康或服务崩溃并正在尝试清理?我试图通过发明一个运行一些后台“睡眠”进程的服务来复制这一点。然而,我可以杀死除最后一个剩余睡眠之外的所有睡眠,而 systemd 并不关心。当我杀死最后一个服务时,systemd 会记录失败的服务。