
지금까지 내 구성은 다음과 같습니다.
foo.경로
[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는 종료되지 않습니다. 이를 수행하기 위해 시스템화할 수 있는 방법이 있습니까? 아니면 작업에 적합한 도구가 아닌가?
답변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)에 바인딩된 프로세스를 종료할 수 있다면(예: 서비스 종료 스크립트의 작업으로 둘 다) 그렇습니다.
저는 애플리케이션 pidfile(catalina.pid)의 내용을 서비스 PIDFile 경로에 기록하는 ExecStartPost 작업을 포함하는 포크된 서비스를 사용하여 <= RHEL-7.7을 실행하는 Tomcat에서 이것을 구현했습니다. 해당 .path 파일의 "PathExists"는 사용자(내 경우에는 권한이 없는)가 시작 스크립트를 호출할 때 시스템 서비스를 연결하기 위해 이 catalina.pid에 나타나는 내용을 추적합니다. 사용자가 종료를 시작하면 애플리케이션 pidfile이 삭제되고 PID(권한 없음)도 정상적으로 종료되며 systemd는 systemd pid 감독의 결과로 서비스를 중지합니다.
현장 서비스:
[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: Supervisor process XXXXXX 이것은 우리의 하위 프로세스가 아닙니다. 종료될 때 알 수 없을 것입니다."라는 메시지를 표시하고 마지막으로 사용자가 작업을 닫아도 systemd 서비스는 중지되지 않습니다.