Java 응용 프로그램에 대한 시스템 서비스를 설정했습니다. Java 애플리케이션이 다시 시작될 때까지 모든 것이 잘 작동합니다. 다시 시작하면 systemd가 관찰하는 기본 Java 프로세스는 상태 0으로 종료되고 자체적으로 새 인스턴스를 시작합니다. Systemd는 이제 프로세스가 종료된 것으로 간주합니다.
다시 시작된 Java 응용 프로그램에서 시작된 프로세스의 새 PID를 systemd에 어떻게 알 수 있습니까?
새로 시작된 프로세스의 PID를 어떻게 얻을 수 있나요?
systemd 서비스는 다음과 같이 정의됩니다.
[Unit]
Description=MyJavaApp
After=network.target
[Service]
Type=simple
User=myuser
ExecStart=/usr/bin/java -jar -Djava.awt.headless=true /opt/MyJavaApp/MyJavaApp.jar &
ExecStop=/usr/bin/java -jar -Djava.awt.headless=true /opt/MyJavaApp/MyJavaApp.jar -quit
[Install]
WantedBy=multi-user.target
답변1
불행하게도 당신은 할 수 없습니다. 에 의해 type=simple
systemd는 실행 프로세스에 대한 인수를 직접 추적합니다 ExecStart
. 비슷한 문제가 여전히 존재 하지만 type=forking
systemd는 프로세스를 추적하고 일단 종료되면 systemd는 프로세스가 죽은 것으로 간주합니다.
이것의 어려움은 systemd가 이것이 애플리케이션의 정상적인 동작인지 알 수 없다는 것입니다. 애플리케이션에는 하위 작업자 프로세스를 생성하는 기본 프로세스가 있을 수 있습니다. 그래서 systemd는 당신의 주인이 죽었고 청소해야 할 일부 아이들이 남았다고 생각할 것입니다.
이 문제를 해결하는 방법에는 두 가지가 있습니다.
- 어떻게든 애플리케이션을 시작하는 systemd에 의해 실행되는 모니터링 프로세스를 생성하십시오. 그런 다음 어떻게든 이 모니터링 프로세스를 통해 애플리케이션 종료와 포크 종료 간의 차이를 알 수 있습니다. 하위 프로세스의 하위 프로세스를 추적하는 것이 쉽지 않기 때문에 구현하기가 매우 어려울 수 있습니다.
한 가지 가능한 접근 방식은 익명 파이프를 생성하고 파이프의 쓰기 끝을 프로세스에 전달한 다음 읽기 끝에서 EOF를 기다리는 것입니다. 애플리케이션이 알 수 없는 파일 설명자를 닫지 않는 한 작동할 것입니다. - 대신 +를 사용하도록 애플리케이션을 변경하세요
exec
. 이런 방식으로 새 프로세스는 이전 프로세스와 동일한 PID를 사용합니다.fork
exec