
Ubuntu 18.04에서 스프링 부트 애플리케이션(다른 사람이 개발함 - 저는 Java 프로그래머가 아님)을 프로비저닝하려고 합니다. 개발자는 이전에 /etc/init.d
서비스를 활성화하기 위해 심볼릭 링크를 추가했습니다. 부팅 시 정상적으로 시작됩니다. 그러나 이후에 서비스가 실패하면 systemd는 여전히 해당 서비스가 실행 중이라고 보고합니다.
[email protected]:/var/log/apps# systemctl status crm-service
● crm-service.service - LSB: crm-service
Loaded: loaded (/etc/init.d/crm-service; generated)
Active: active (exited) since Wed 2020-04-15 12:27:15 BST; 3h 56min ago
Docs: man:systemd-sysv-generator(8)
Process: 8656 ExecStop=/etc/init.d/crm-service stop (code=exited, status=0/SUCCESS)
Process: 8703 ExecStart=/etc/init.d/crm-service start (code=exited, status=0/SUCCESS)
Apr 15 12:27:15 example.com systemd[1]: Starting LSB: crm-service...
Apr 15 12:27:15 example.com crm-service[8703]: /var/services/crm-service.conf: line 1: -Xms96M: command not found
Apr 15 12:27:15 example.com crm-service[8703]: Started [8747]
Apr 15 12:27:15 example.com systemd[1]: Started LSB: crm-service.
내가 보는 동안동일한 시스템 단위 파일인터넷 전체에 게시된 springboot에 대해서는 이 문제를 해결할 수 있는 내용이 아무것도 없습니다.
- 서비스의 실제 상태를 확인하려면 어떻게 시스템화해야 합니까? (리스닝 소켓이 열리지만 임의의 높은 포트에서 열립니다)
- 시도해볼 수 있는 방법이 있나요?부드럽게실패한 서비스를 다시 시작하려면 어떻게 해야 합니까?
답변1
Systemd에는 많은 비평가가 있으며 그 중 상당수는 꽤 괜찮지만 그렇지 않습니다.Systemd는 시작 스크립트에서 분기된(또는 복제된) 모든 프로세스와 스레드를 추적할 수 있으며, 아무것도 남아 있지 않으면 서비스가 중단된 것으로 간주합니다.
내가 볼 수 있는 첫 번째 문제는 systemd가 에서 시작/중지 스크립트를 사용하지 않는다는 것입니다 /etc/init.d
. 이는 단지 호환성 애드온일 뿐입니다. 대신 systemd는 단위 파일, 즉 모든 서비스에 대한 구성 파일을 사용합니다.
systemd sysv init compat 모듈은 .NET의 모든 서비스에 대한 단위 파일을 효과적으로 생성합니다 /etc/init.d
. init 스크립트가 필요한 정보를 놓치거나 정보를 추출하는 것이 불가능하기 때문에 이것이 항상 괜찮은 것은 아닙니다.
이 compat 모듈은 systemd가 init 스크립트가 실패했다고 간주하여 종료 코드가 0이 아닌 경우 서비스가 작동하지 않는 것으로 작동합니다. 종료 코드가 0이면 성공적인 실행을 의미합니다. init 스크립트에 버그가 있고 실패 시에도 0 종료 코드를 제공하면 systemd를 속이게 됩니다.
init 스크립트 버그의 가장 가능성 있는 원인은 백그라운드에서 프로세스를 시작한 다음 항상 0으로 종료된다는 것입니다. 사용자 지정 공급자가 작성한 대부분의 초기화 스크립트에 대한 나의 일반적인 경험은... 아마도 대부분 개선의 여지가 있다는 것입니다. 그들을 믿지 말고, 그들이 무엇을 하는지 보고 고치십시오. 귀하의 경우에는 확인하는 것이 가장 좋습니다.
- Java 앱을 시작하는 방법
- 어디서 시작되나요?
- 어떤 사용자가 시작합니까?
그리고 유닛 파일로 동일한 기능을 재현합니다.
systemd에서는 initscript를 자동으로 다시 시작할 수 있는 방법이 없지만 유닛 파일에서는 가능합니다.
Java 프로그램이 임의로 충돌하는 경우에도 심각한 문제가 됩니다. 모든 정상적인 Java 프레임워크는 자신의 치명적인 오류를 올바르게 처리합니다(모든 예외를 포착하고 기록하고 계속합니다).
init 스크립트의 또 다른 가능성이 높은 버그는 JVM(대부분: /usr/bin/java)을 찾지 못해 빈 문자열로 대체하여 JVM 플래그를 쉘 명령으로 시작하려고 시도한다는 것입니다. . 분명히 -Xms96M
시스템에는 명령이 없지만 /usr/bin/java -Xms96M ...
작동할 것입니다.
스프링 부트 앱의 단위 파일 예:
[Unit]
Description=Crm Spring Boot App Example
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/java -Xms96M ...other flags... your.spring.boot.jar
User=exampleuser
Group=examplegroup
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=exampleapp
WorkingDirectory=/path/to/app/home
[Install]
WantedBy=multi-user.target
Alias=exampleapp.service
또한 이 단위 파일은 Java 프로세스의 표준 출력 및 오류를 syslog로 리디렉션합니다.
앱을 자동으로 다시 시작하려면 다음을 삽입하세요.
RestartSec=5s
Restart=on-failure
섹션 으로 [Service]
.
에 대한 시스템 튜토리얼이 있습니다GoLinuxCloud.com.