foo.path

foo.path

到目前为止我的配置是:

foo.path

[Path] 
PathExists=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

foo.service

[Unit]
Description=Matt Test
BindsTo=foo.path

[Service]
ExecStart=/bin/sh /home/mpekar/bin/foo.sh 
PIDFile=/run/foo.pid

这在启动时工作正常,但当 /tmp/foo.path 被删除时 foo.service 不会被终止。有没有办法让 systemd 做到这一点,或者它只是不适合这项工作的工具?

答案1

我会尝试这个。使用 PathChanged 创建附加服务:

foo-stop.path

[Path] 
PathChanged=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

然后创建:foo-stop.service

让其“ExecStart”脚本检查是否/tmp/foo.path已被删除(因为 PathChanged 也可能会触发其他更改)。如果路径已被删除,请让脚本调用/bin/systemctl stop foo.

答案2

如果您能够在删除 /tmp/foo.path 时终止绑定到 PIDFile (/run/foo.pid) 的进程(例如,两者都作为服务关闭脚本中的操作),那么可以。

我在运行 <= RHEL-7.7 的 Tomcat 上实现了这一点,并使用分叉服务,其中包括 ExecStartPost 操作,该操作将应用程序 pidfile (catalina.pid) 的内容记录到服务 PIDFile 路径中。相应的 .path 文件中的“PathExists”会跟踪此 catalina.pid 上出现的内容,以便在用户(在我的情况下为无特权)调用启动脚本时挂钩 systemd 服务。当用户启动关闭时,应用程序 pidfile 被删除,PID(也是非特权的)优雅地终止,并且 systemd 停止服务作为 systemd pid 监督的结果。

poc.服务:

[nouser@nohost system]# cat poc.service
# . . .
[Unit]
After=network.target
After=%p.path
Wants=%p.path
# . . . 
[Service]
Type=forking
Environment="%p_APPLICATION_PID_FILE=/opt/%p/logs/catalina.pid"
PIDFile=/var/run/%p.pid
ExecStart=/bin/sh -c '/path/to/tomcat/control/script/invoked/with/su/hypen start'
ExecStartPost=/bin/sh -c 'cat ${%p_APPLICATION_PID_FILE} > $(systemctl show %n -p PIDFile|cut -f2- -d"=")'
ExecStop=/bin/sh -c '/path/to/tomcat/control/script/invoked/with/su/hypen stop'
# . . .

poc.路径:

[nouser@nohost system]# cat poc.path
# . . .
[Path]
PathExists=/opt/%p/logs/catalina.pid
# . . .

这种方式也适用于 Spring Boot 应用程序。但由于它们天生就挂在 bash 进程上,我必须立即终止该父进程,以强制 PID 1 成为应用程序父进程。如果没有,journalctl 会显示一条消息“*.service:监督进程 XXXXX 这不是我们的子进程。我们很可能不会注意到它何时退出。”,并且最后 systemd 服务不会在用户关闭操作时停止。

相关内容