프로그래밍/운영체제

systemd Restart 정책 기준 정리

포도알77 2026. 6. 15. 11:25

본문 중간의 쿠팡 추천 상품 구매시 쿠팡 파트너스에서 일정액의 수수료를 제공받습니다.

systemd Restart 정책 기준 정리

Restart=는 서비스가 종료됐을 때 언제 다시 띄울지, RestartSec=는 얼마나 기다렸다가 다시 띄울지, StartLimitIntervalSec=StartLimitBurst=는 재시도 폭주를 어디서 끊을지를 정하는 설정이다. 2026년 6월 15일 기준 upstream systemd 공식 문서를 보면 장기 실행 서비스의 기본 선택지는 대체로 Restart=on-failure이고, 시작 제한은 별도로 생각해야 한다.

실무에서 자주 생기는 문제는 두 가지다. 실패 복구를 위해 자동 재시작을 켰는데 정상 종료까지 다시 올라오거나, 반대로 장애가 반복될 때 재시작이 너무 빠르게 반복되어 로그만 쌓이는 경우다. 이 글은 공식 문서 기준으로 각 옵션의 의미와 무난한 선택 기준만 정리한다.

Restart=는 무엇을 기준으로 동작할까?

systemd 공식 문서에 따르면 Restart=는 메인 프로세스의 종료뿐 아니라 ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost=, ExecReload=에 지정한 프로세스 종료와 일부 timeout까지 포함해 재시작 여부를 판단한다. 다만 systemctl stop처럼 systemd가 의도적으로 내린 종료는 재시작 대상이 아니다.

같은 문서에서 clean exit은 기본적으로 종료 코드 0, 그리고 Type=oneshot이 아닐 때 SIGHUP, SIGINT, SIGTERM, SIGPIPE로 설명된다. 여기에 SuccessExitStatus=를 추가하면 특정 종료 코드를 정상 종료로 더 넓게 볼 수 있다.

어떤 Restart= 값을 먼저 검토하면 될까?

의미 우선 고려할 상황
no 자동 재시작 안 함 실패 후 운영자 판단이 필요한 작업성 서비스
on-failure 비정상 종료, signal 종료, timeout, watchdog 시 재시작 대부분의 장기 실행 데몬
on-abnormal signal 종료, timeout, watchdog일 때만 재시작 애플리케이션이 스스로 종료 코드로 종료 의사를 표현할 수 있을 때
on-watchdog watchdog timeout일 때만 재시작 watchdog 기반 장애만 별도로 보고 싶을 때
always 정상 종료까지 포함해 거의 항상 재시작 상시 상주가 절대 조건인 프로세스이면서 정상 종료 개념이 사실상 없을 때

공식 문서는 장기 실행 서비스라면 on-failure를 권장 선택지로 본다. 이유는 오류 복구를 시도하면서도 의도적인 정상 종료까지 다시 띄우는 부작용을 피하기 쉽기 때문이다.

반대로 배치형 작업이나 상태 점검 도구처럼 종료 코드로 "이번 실행은 여기까지"를 표현하는 프로그램은 on-abnormal이 더 맞을 수 있다. 이 경우 비정상 신호 종료나 timeout은 다시 시도하되, 애플리케이션이 스스로 끝낸 정상 종료는 그대로 받아들일 수 있다.

RestartSec=를 왜 꼭 같이 봐야 할까?

공식 문서 기준 RestartSec=의 기본값은 100ms다. 즉 Restart=on-failure만 켜 두면 실패 직후 매우 짧은 간격으로 재시작을 시도할 수 있다.

이 기본값이 항상 잘못된 것은 아니지만, 설정 오류나 포트 충돌처럼 즉시 반복 실패하는 장애에서는 너무 공격적일 수 있다. 로그 회전 부담, 외부 의존성 과부하, rate limit 조기 도달을 생각하면 대부분의 네트워크 서비스는 몇 초 단위 지연을 주는 편이 운영상 읽기 쉽다.

예를 들어 외부 DB 연결이 잠깐 흔들릴 수 있는 API 서버라면 RestartSec=3s 또는 5s처럼 완만한 간격이 무난하다. 반면 아주 짧은 장애에도 즉시 복구가 중요하고 실패 원인이 일시적이라고 보는 로컬 보조 프로세스는 더 짧은 간격이 맞을 수 있다.

 

 

StartLimitIntervalSec=StartLimitBurst=는 무엇을 막을까?

Restart=가 "다시 시작할지"를 정한다면, StartLimitIntervalSec=StartLimitBurst=는 "얼마나 자주 시작을 허용할지"를 정한다. 공식 문서에 따르면 정해진 interval 안에서 burst 횟수를 넘기면 더 이상 시작이 허용되지 않는다.

중요한 점은 이 제한이 자동 재시작에만 적용되지 않는다는 것이다. upstream 문서는 수동 시작까지 포함한 모든 start에 적용된다고 설명한다. 그래서 서비스가 계속 실패한 뒤 systemctl start를 눌렀는데 바로 안 올라오는 상황은 이 설정과 연관될 수 있다.

또한 공식 문서는 systemctl reset-failed가 rate counter를 비우는 데 쓰인다고 설명한다. 즉 원인을 고친 뒤 즉시 다시 올려야 할 때는 단순 start보다 reset 후 start가 필요한 경우가 있다.

운영에서 무난한 조합은 어떻게 잡을까?

상황 무난한 출발점 이유
일반적인 웹 API, 워커, 에이전트 Restart=on-failure + RestartSec=3s 비정상 종료는 복구하고 재시작 폭주는 완화
정상 종료 코드가 의미 있는 배치형 데몬 Restart=on-abnormal 프로그램이 의도적으로 종료한 경우까지 다시 띄우지 않음
짧은 시간에 반복 실패 가능성이 큰 서비스 Restart=on-failure + 시작 제한 추가 장애 반복 시 무한 재시작 루프를 차단

구체적인 숫자는 애플리케이션 특성에 따라 달라진다. 다만 재시작 정책과 시작 제한을 분리해서 생각하면 판단이 쉬워진다. 먼저 실패 시 다시 띄울지 정하고, 그다음 너무 자주 띄우는 것을 어디서 멈출지 정하는 순서가 안전하다.

정상 종료를 예외 처리해야 하면 무엇을 쓸까?

애플리케이션이 특정 종료 코드를 "재시작하지 말아야 하는 종료"로 사용한다면 RestartPreventExitStatus=를 함께 볼 수 있다. 공식 문서 기준 이 옵션은 메인 서비스 프로세스가 특정 종료 코드를 반환했을 때, Restart= 설정과 무관하게 자동 재시작을 막는다.

반대로 특정 종료 코드는 강제로 재시작 대상으로 보고 싶다면 RestartForceExitStatus=가 있다. 다만 이 두 옵션은 보조 명령이 아니라 메인 서비스 프로세스 기준으로 해석되므로, pre/post hook의 실패 제어까지 동일하게 된다고 보면 안 된다.

자주 헷갈리는 질문

Q. Restart=always가 가장 안전한 기본값일까?

그렇게 보기 어렵다. 정상 종료까지 다시 띄우므로, 프로그램이 의도적으로 종료해도 계속 살아나야 하는 프로세스가 아니라면 과한 설정이 될 수 있다. 장기 실행 데몬의 기본 선택지는 공식 문서 기준으로 on-failure가 더 무난하다.

Q. Type=oneshot에도 같은 기준을 적용할 수 있을까?

공식 문서는 Type=oneshot에 대해 clean exit 기준의 자동 재시작에서 제한이 있다고 설명한다. 특히 alwayson-success는 허용되지 않는다. 그래서 일회성 작업 서비스는 장기 실행 데몬과 같은 재시작 전략으로 보면 안 된다.

Q. 시작 제한에 걸리면 영구적으로 막힐까?

아니다. 공식 문서 기준 interval이 지난 뒤에는 다시 시작을 시도할 수 있고, 관리자가 systemctl reset-failed로 카운터를 비울 수도 있다. 다만 원인 수정 없이 반복 시작만 하면 같은 제한에 다시 걸릴 수 있다.

정리

Restart=는 장애 복구 정책이고, RestartSec=는 재시도 간격, StartLimitIntervalSec=StartLimitBurst=는 재시도 상한선이다. 이 셋을 분리해서 보면 대부분의 서비스는 Restart=on-failure를 시작점으로 삼고, 서비스 특성에 맞는 지연과 시작 제한을 추가하는 식으로 정리할 수 있다.

2026년 6월 15일 기준 upstream systemd 공식 문서를 기준으로 보면 장기 실행 서비스에 가장 흔한 실수는 재시작 여부만 정하고 재시도 간격과 rate limit을 비워 두는 것이다. 자동 복구가 필요할수록 재시작 정책과 폭주 방지 정책을 같이 적는 편이 안전하다.

참고 자료

반응형
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사