홈 › 리눅스 운영 › 03 / 13

프로세스·서비스 관리 (systemd)

섹션 7진행 0 / 13

4. 응용 변형 예제

4.1 실패 진단 순서

systemctl start 가 실패했을 때 보는 순서입니다.

bash
systemctl status myapp --no-pager -l     # 1. 종료 코드와 마지막 줄
journalctl -u myapp -n 50 --no-pager     # 2. 앱 로그
journalctl -xe                           # 3. systemd 자체 메시지
sudo -u myapp /usr/bin/java -jar /opt/myapp/current/app.jar   # 4. 직접 실행

네 번째 단계가 결정적입니다. 서비스 계정으로 직접 띄워 보면 권한 오류나 경로 오류가 화면에 그대로 나옵니다.

4.2 여러 인스턴스 — 템플릿 유닛

같은 jar 를 포트만 바꿔 두 개 띄울 때 [email protected] 템플릿을 씁니다.

ini
[Service]
ExecStart=/usr/bin/java -jar /opt/myapp/current/app.jar --server.port=%i

systemctl start myapp@8080 myapp@8081 처럼 @ 뒤 값이 %i 로 들어갑니다. 로그는 journalctl -u myapp@8080 으로 따로 봅니다.

4.3 pkill 과 killall

PID 를 찾지 않고 이름으로 신호를 보냅니다. 편리하지만 범위가 넓어 운영 서버에서는 조심합니다.

bash
pkill -f 'app.jar'              # 명령줄에 app.jar 가 있는 모든 프로세스
pkill -TERM -u myapp java       # myapp 계정의 java 만

systemd 로 관리하는 서비스는 pkill 대신 systemctl stop 을 씁니다. pkill 로 죽이면 Restart=on-failure 가 즉시 다시 띄워 정지가 안 됩니다.

4.4 재시작 폭주 막기

앱이 시작 직후 계속 죽으면 systemd 는 5초마다 재시작을 반복합니다. 두 키로 상한을 둡니다.

ini
[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5

5분 안에 5번 실패하면 재시작을 멈추고 failed 상태로 남깁니다. 원인을 고친 뒤 systemctl reset-failed myapp 으로 카운터를 지우고 다시 시작합니다.

4.5 부팅 순서 — DB 뒤에 뜨기

같은 서버의 DB 나 Redis 뒤에 떠야 하면 After 에 그 서비스를 적습니다.

ini
[Unit]
After=network-online.target postgresql.service
Wants=network-online.target

After 는 순서만 정하고 Requires 는 의존까지 겁니다. 외부 DB 서버라면 순서로 해결이 안 되므로 앱 쪽 재시도 로직이나 Restart=on-failure 에 기대는 편이 현실적입니다.