이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
systemd와 Service 관리에서 붙잡아야 할 핵심 판단 기준은 무엇인가?service 설정은 운영 중 실행 계약이다라는 기준은 어떤 JVM/OS 신호로 확인되는가?- Java/Spring 코드에서 “Environment=SPRING_PROFILES_ACTIVE=prod
같은 unit 설정은 Spring profile과 bean 구성을 바꾼다흐름은 어떤 장애 신호로 드러나는가?
개요
이 문서의 주제는 systemd와 Service 관리이다. systemd service가 Java 서버의 실행 환경, 재시작, 로그, limit을 어떻게 관리하는지 설명한다.
먼저 붙잡을 기준은 다음 문장이다. service 설정은 운영 중 실행 계약이다. Spring Boot jar가 어떤 user, environment, working directory, restart policy, limit으로 실행되는지는 코드가 아니라 systemd service 파일과 실제 process 상태가 결정한다.
핵심 모델
- 판단 기준: service 설정은 운영 중 실행 계약이다.
- systemd service는 Java process의 생명주기, 실행 user, 환경변수, working directory, restart policy를 관리한다.
ExecStart와 실제 process command line이 다르면 drop-in override, 배포 스크립트, reload 누락을 확인해야 한다.LimitNOFILE,MemoryMax, environment 설정은 socket, dump, GC log, profile 동작에 직접 영향을 준다.- Restart policy는 장애 완화 장치이지만 crash loop와 원인 로그를 빠르게 덮을 수 있다.
- Service 변경 후에는
daemon-reload, restart, 실제 process 반영 여부를 따로 검증해야 한다.
문서별 핵심 구분
- systemd service는 실행 user, 환경변수, restart, limit을 관리한다.
- service 파일과 실제 process command line은 다를 수 있다.
- restart policy는 완화 장치이지만 crash loop를 숨길 수 있다.
원리
systemd service 파일은 운영에서 실행되는 애플리케이션의 계약서다. ExecStart, User, WorkingDirectory, Environment, Restart, LimitNOFILE 같은 항목은 Java 코드 바깥에서 장애 양상을 바꾼다.
예를 들어 로컬에서는 heap dump가 생성되지만 운영에서는 실패한다면 코드 문제가 아니라 service user의 write 권한, working directory, disk limit 문제일 수 있다. 낮은 port bind 실패도 root 여부보다 capability와 service user 설정으로 봐야 한다.
systemctl cat은 정의를 보여 주고, systemctl show는 systemd가 인식한 속성을 보여 주며, ps는 실제 실행 중인 process를 보여 준다. 세 결과가 일치해야 “설정이 적용됐다”고 말할 수 있다.
Restart policy는 장애 시 자동 복구를 도와주지만, 반복 crash를 빠르게 감춰 로그와 dump 수집 기회를 줄일 수 있다. 따라서 재시작 횟수와 exit reason은 장애 타임라인에서 반드시 확인한다.
Java/Spring 연결
Environment=SPRING_PROFILES_ACTIVE=prod같은 unit 설정은 Spring profile과 bean 구성을 바꾼다.ExecStart의 JVM option은 heap, GC log, agent, dump 경로를 결정하므로 배포 산출물처럼 검토해야 한다.User와WorkingDirectory가 잘못되면 config 파일, keystore, log, heap dump 접근 실패가 Spring 예외로 나타난다.Restart=on-failure는 장애 완화에 유용하지만 Actuator나 알림보다 빠르게 process를 되살려 원인 증거를 줄일 수 있다.LimitNOFILE은 Tomcat connection과 outbound client pool 상한에도 영향을 주므로 socket 장애와 함께 본다.- Spring 코드 리뷰에서는
systemd와 Service 관리판단 기준이 어떤 thread, pool, timeout, resource 설정으로 드러나는지 확인한다.
코드와 설정 예시
[Service]
User=app
WorkingDirectory=/opt/my-app
Environment="SPRING_PROFILES_ACTIVE=prod"
LimitNOFILE=65535
Restart=on-failure
ExecStart=/usr/bin/java -Xms1g -Xmx1g -jar app.jar이 예시는 service 파일이 단순 실행 스크립트가 아니라 운영 조건을 정의한다는 점을 보여 준다. JVM option, profile, FD limit, working directory가 바뀌면 같은 jar도 전혀 다른 장애 양상을 만든다.
관찰 명령
systemctl status my-app
systemctl cat my-app
systemctl show my-app --property=User,LimitNOFILE,Restartsystemd와 Service 관리 관찰 명령은 결론이 아니라 가설 확인 도구다. 운영 중에는 반복 간격, 대상 PID, 수집 시각을 함께 남기고 출력이 큰 명령은 범위를 제한한다.
지표 해석
| 신호 | 먼저 의심할 것 | 다음 확인 |
|---|---|---|
Active=failed | process 종료, exit code | systemctl status, journalctl |
| restart count 증가 | crash loop, OOM kill, config error | systemctl show, journalctl |
| 실제 args와 service 파일 불일치 | reload/restart 누락, override | systemctl cat, ps |
| FD limit 낮음 | socket/file open 실패 | LimitNOFILE, /proc/<pid>/limits |
systemd와 Service 관리에서는 핵심 신호와 보조 지표를 같은 시간축에서 맞춘다. 먼저 변한 신호와 뒤따라 포화된 신호를 분리해야 원인과 결과를 구분할 수 있다.
장애 상황에서 보는 순서
systemctl status로 active state, PID, exit reason, 최근 로그를 확인한다.systemctl cat으로 service 원본과 drop-in override를 확인한다.systemctl show와/proc/<pid>/limits로 실제 limit과 restart 정책을 본다.ps로 실제 command line, user, working directory 반영 여부를 맞춘다.- 설정 수정 후에는
daemon-reload, restart, 실제 process 반영을 각각 검증한다.
이 순서는 systemd와 Service 관리 후보를 빠르게 좁히기 위한 기본 루틴이다. 결론을 내리기 전에는 애플리케이션 증거와 JVM/OS 증거를 최소 한 번 이상 맞춘다.
실전 팁
systemctl cat만 보고 끝내지 말고 실제pscommand line과/proc/<pid>/limits를 확인한다.- service user가 dump, log, config, keystore 경로에 접근할 수 있는지 배포 전에 검증한다.
- Restart policy가 켜져 있으면 장애 시간대 restart count와 exit code를 먼저 남긴다.
- Drop-in override를 썼다면 원본 unit과 override가 충돌하지 않는지 같이 본다.
- 장애 회고에는 service 파일 변경 여부와 실제 반영 시각을 남긴다.
주니어 팁
- Unit 파일을 볼 때 service가 process 실행 조건을 정한다는 점을 먼저 확인한다.
systemctl cat,systemctl show,ps는 서로 다른 층의 증거라는 차이를 익힌다.- 설정을 바꾼 뒤에는
daemon-reload와 restart 여부를 반드시 확인한다.
시니어 팁
- Service unit은 애플리케이션 배포 산출물처럼 버전 관리하고 리뷰한다.
- Restart policy는 alert, dump 수집, crash loop 차단 기준과 함께 설계한다.
- 운영 표준에는 JVM option, profile, user, limit, working directory를 검증하는 배포 체크를 둔다.
Guru급 팁
systemd와 Service 관리주제는 단일 snapshot보다 변화 방향이 중요하다. 같은 명령을 간격을 두고 실행해 상태가 증가, 유지, 회복 중 어디인지 본다.- 고급 도구는
systemd와 Service 관리가설을 좁힐 때만 사용하고 기본 지표와 모순되는지 먼저 확인한다. systemd와 Service 관리조치 후에는 CPU, memory, socket, disk, pool 중 다음 포화 지점이 어디로 이동했는지 확인한다.
위험 신호!
- Service 파일을 수정하고
daemon-reload나 restart 반영 여부를 확인하지 않는다. systemctl status의 최근 로그만 보고 전체 crash loop 이력을 놓친다.LimitNOFILE이 unit에 있어도 실제 process limit을 확인하지 않는다.- 권한 문제를 root 실행으로 덮어 운영 위험을 키운다.
- Restart policy 때문에 사라진 원인 로그와 dump를 수집하지 못한다.
확인 질문
확인 질문
- service 파일과 실제 process가 다를 수 있는 이유는 무엇인가?
- Drop-in override, reload 누락, restart 누락, 배포 스크립트 차이 때문에 systemd 정의와 실행 중 process가 달라질 수 있기 때문이다.
LimitNOFILE변경이 적용됐는지 어떻게 확인하는가?
systemctl show, service 재시작 여부,/proc/<pid>/limits의 실제 값을 함께 확인해야 한다.- Restart policy가 장애 분석을 어렵게 만드는 이유는 무엇인가?
- process가 자동으로 다시 떠서 exit reason, dump, 재현 조건이 사라지고 crash loop가 정상 복구처럼 보일 수 있기 때문이다.