서비스가 잠깐 실행됐다가 종료되고 다시 실행되는 상황에서는 재시작 횟수만 늘려도 같은 오류가 반복될 수 있습니다. 프로세스가 끝난 이유와 systemd가 다시 실행한 조건을 나누어 봐야 합니다. 이 글은 systemd를 사용하는 Linux의 시스템 서비스에서 종료 기록, 재시작 간격, 의존 서비스의 상태를 확인하는 순서를 설명합니다. 예시의 app.service는 실제 점검할 서비스 이름으로 바꿉니다.

마지막 실패 표시보다 먼저 발생한 종료 기록 확인
우선 현재 상태와 이번 부팅의 서비스 로그를 함께 확인합니다. systemctl status는 최근 메시지 일부만 보여 주므로, 반복이 시작된 시점의 기록은 journalctl로 더 넓게 읽습니다. 옵션 중 -b는 이번 부팅으로 범위를 좁히며, 로그 접근 권한이 부족하면 관리자 권한이 필요합니다.
systemctl status app.service --no-pager -l
journalctl -u app.service -b --since "30 minutes ago" --no-pager
systemctl show app.service -p Result -p ExecMainCode -p ExecMainStatus -p NRestarts
종료 코드, 종료 신호, 시간 초과 중 무엇이 기록됐는지 구분합니다. 비정상 종료 코드 자체만으로 설정 오류라고 확정할 수는 없습니다.
종료 직전의 애플리케이션 메시지에서 설정 파일 경로, 접근 거부, 외부 연결 실패 등을 찾고 같은 시각의 systemd 메시지와 연결합니다.
예를 들어 설정 파일을 읽지 못했다는 메시지 뒤에 재시도와 start-limit-hit가 이어졌다면, 먼저 조사할 대상은 파일 경로와 실행 계정의 읽기 권한입니다. 이는 가정 사례이며, start-limit-hit는 시작 횟수 제한에 걸렸다는 결과입니다. 그 이전의 실패 이유를 대신 설명하지 않습니다.

종료 원인과 재시작 조건·간격 구분
systemctl cat으로 기본 유닛과 추가 설정인 drop-in을 확인합니다. show는 관리자가 현재 로드한 속성을 확인하는 데 사용합니다. 파일만 수정하고 반영하지 않은 상태라면 두 결과를 대조하는 것이 도움이 됩니다.
systemctl cat app.service
systemctl show app.service -p Restart -p RestartUSec -p StartLimitIntervalUSec -p StartLimitBurst
Restart=on-failure는 비정상 종료나 시간 초과 같은 실패에 재시작을 적용합니다. Restart=always는 정상 종료도 다시 실행할 수 있으므로, 정상적으로 끝나는 프로그램이 반복 실행되는 경우에는 작업 성격과 정책이 맞는지 확인합니다. 단, Type=oneshot에는 always를 사용할 수 없습니다. 수동 stop으로 정지한 서비스를 이 설정이 즉시 다시 켠다고 해석해서도 안 됩니다.
RestartSec는 재시작 전 대기 간격이며 실패 원인을 고치는 기능은 아닙니다. 아래는 상시 실행 서비스에 검토할 수 있는 설정 예시입니다. 60초와 5회는 권장 기본값이 아니라 설명용 값이며, 실제 간격과 제한은 복구 목표와 외부 시스템의 부담에 맞춰 정합니다.
[Unit]
StartLimitIntervalSec=60s
StartLimitBurst=5
[Service]
Restart=on-failure
RestartSec=5s
시작 제한은 자동 재시작뿐 아니라 수동 시작에도 적용됩니다. 제한에 걸린 뒤 시간이 지났다고 자동 재시도가 저절로 재개된다고 기대하지 말고, 원인 조치 후 명시적인 시작을 검토합니다. 간격을 늘려 DB 준비를 기다리는 방식은 영구적인 접속 오류를 일시적으로 감출 수도 있습니다.
근거: systemd.service — Restart·RestartSec·서비스 유형
의존 서비스의 시작 순서와 준비 상태 비교
DB나 다른 서비스에 연결하지 못해 종료된다면 두 서비스의 로그 시각을 대조합니다. After=는 둘 다 시작될 때의 순서를 정하지만 상대 유닛을 시작하도록 끌어오지는 않습니다. 함께 시작할 필요는 Wants= 또는 Requires= 같은 의존 설정과 별도로 판단합니다.
또한 systemd가 시작 완료로 판단한 시점이 업무 요청을 받을 준비가 된 시점과 항상 같지는 않습니다. Type=simple인 서비스는 프로세스를 생성한 직후 시작된 것으로 간주될 수 있습니다. 준비 통지를 지원하는 Type=notify 등의 구성 여부와 실제 DB 연결 가능 상태를 함께 확인해야 합니다.
제 판단으로는 고정 대기 시간만 추가하기 전에 애플리케이션의 제한된 연결 재시도와 준비 상태 확인 방식을 검토하는 편이 낫습니다. 로컬 의존 서비스가 이미 정상인데도 계속 실패한다면 접속 주소, 인증 정보, 서비스 계정의 실행 환경으로 조사 대상을 좁힙니다. After=만 추가해 모든 접속 실패가 해결된다고 단정할 수 없습니다.

원인 조치 후 한 번의 복구와 업무 동작 검증
필요한 로그를 확보한 뒤 반복 실행이 장애를 키우면 서비스 중단 영향을 확인하고 systemctl stop app.service로 잠시 멈출 수 있습니다. 유닛 정책 변경은 systemctl edit app.service로 drop-in을 작성하는 방식을 검토합니다. 설정 변경 후에는 아래 순서로 반영하고 복구를 확인합니다.
sudo systemctl daemon-reload
sudo systemctl reset-failed app.service
sudo systemctl start app.service
systemctl status app.service --no-pager -l
journalctl -u app.service -b --since "5 minutes ago" --no-pager
이 순서는 서비스를 멈춘 뒤 수정한 경우의 예시입니다. daemon-reload는 유닛 설정을 다시 읽는 작업이며 실행 중인 애플리케이션을 재시작하지 않습니다. reset-failed는 실패 상태와 시작 제한 카운터 등을 초기화하지만 오류를 수리하지는 않습니다. 관찰된 실패 주기를 넘겨 상태를 보고, 실제 요청이나 작업 처리까지 확인해야 복구 여부를 판단할 수 있습니다.
근거: systemctl — 상태 조회·설정 반영·실패 초기화
자주 묻는 질문
재부팅하면 해결된 것으로 볼 수 있습니까?
부팅 순서나 외부 서비스 상태가 달라져 증상이 잠시 사라질 수 있습니다. 재부팅 전후 로그와 설정을 비교하고 같은 조건에서도 동작하는지 확인해야 합니다.
서비스 로그에 아무것도 없으면 어떻게 합니까?
표준 출력이 저널로 전달되는지와 애플리케이션의 별도 로그 경로를 확인합니다. 이번 부팅에 기록이 없다면 조회 기간과 로그 보관 상태도 살펴봅니다.
최신 문서의 옵션을 그대로 써도 됩니까?
배포판의 systemd 버전에 따라 지원 옵션이 다를 수 있습니다. systemctl --version과 서버의 man systemd.service, man systemd.unit을 함께 확인합니다.
결론
반복 재시작을 점검할 때는 첫 오류, 다시 실행된 조건, 제한에 걸린 시점을 구분합니다. 기록으로 원인 후보를 좁힌 뒤 정책을 조정하고, 의존 서비스의 준비 상태와 실제 업무 처리까지 확인합니다. 재시도 횟수보다 중요한 것은 같은 실패가 다시 발생하는 조건을 찾아 없애는 일입니다.