
systemd Type=notify 기준 정리
Type=notify는 서비스가 실제로 준비를 마친 시점에 sd_notify()로 READY=1을 보내고, 그때 systemd가 후속 유닛 시작을 진행하게 만드는 방식이다. 2026년 6월 22일 기준 upstream systemd 공식 문서를 보면 장기 실행 서비스의 기본값으로는 대체로 Type=exec가 권장되지만, 서비스 코드가 자신의 준비 완료 시점을 정확히 알고 있고 그 시점을 systemd에 알려야 한다면 Type=notify가 더 맞다.
실무에서 자주 헷갈리는 지점은 두 가지다. 단순히 프로세스 실행 성공만 확인하면 되는지, 아니면 포트 바인딩이나 내부 초기화까지 끝난 뒤에 다른 유닛이 따라오게 해야 하는지다. 이 글은 Type=notify, NotifyAccess=, sd_notify()의 의미와 무난한 선택 기준만 정리한다.
Type=notify는 무엇을 바꿀까?
upstream systemd.service 문서에 따르면 Type=notify는 동작 방식이 Type=exec와 비슷하지만, 서비스가 시작 완료를 알리는 READY=1 메시지를 보낼 때까지 systemd가 follow-up unit 시작을 미룬다. 반대로 Type=exec는 서비스 바이너리의 execve() 성공까지만 확인하고 다음 작업으로 넘어간다.
이 차이는 의존 관계가 있는 서비스에서 중요하다. 예를 들어 데몬이 프로세스는 떴지만 실제로는 포트 바인딩, 캐시 로딩, 초기 동기화가 끝나야 요청을 받을 수 있다면 Type=exec만으로는 너무 이르게 시작 성공으로 판단될 수 있다.
먼저 어떤 타입을 고르면 될까?
| 타입 | systemd가 시작 완료로 보는 시점 | 우선 고려할 상황 |
|---|---|---|
simple |
fork 직후 | 대기 없이 바로 다음 작업을 진행해도 되는 매우 단순한 서비스 |
exec |
execve() 성공 직후 |
장기 실행 서비스의 기본 출발점 |
notify |
서비스가 READY=1을 보낸 뒤 |
서비스 코드가 준비 완료 시점을 직접 알려야 할 때 |
forking |
부모 프로세스 종료 뒤 | 기존 데몬화 방식을 유지해야 하는 레거시 서비스 |
공식 문서는 장기 실행 서비스에 대해 Type=exec를 권장 선택지로 설명한다. 서비스 실행 파일이 없거나 User= 같은 실행 준비 단계에서 실패했을 때 이를 제대로 추적하기 쉽기 때문이다. 다만 서비스 코드 내부 초기화 완료 시점에 맞춰 정확히 순서를 제어해야 하면 notify, D-Bus 이름 획득이 준비 완료 조건이면 dbus가 더 적합하다.
Type=notify를 고를 만한 기준은 무엇일까?
첫째, 후속 유닛이나 클라이언트가 "프로세스가 떴다"가 아니라 "서비스가 실제로 준비됐다"는 신호를 필요로 할 때다. 공식 문서 기준 notify는 서비스 코드가 정확히 언제 준비 완료로 볼지 결정할 수 있게 해 준다.
둘째, 서비스가 reload 완료나 watchdog keep-alive까지 systemd와 같은 채널로 통신해야 할 때다. upstream 문서는 notify-reload와 WatchdogSec= 모두 notification socket 사용을 전제로 설명한다.
반대로 서비스 코드에 sd_notify() 지원이 없고, 준비 완료 시점을 외부에서 확실히 알 수 없다면 Type=notify를 억지로 고르는 것이 맞지 않다. 이런 경우에는 Type=exec를 쓰거나, 레거시 데몬이면 forking을 유지하는 편이 더 단순하다.
NotifyAccess=는 왜 같이 봐야 할까?
Type=notify는 notification socket에 메시지를 보내는 방식이므로, 어떤 프로세스의 메시지를 systemd가 신뢰할지 정하는 NotifyAccess=를 같이 봐야 한다. 공식 문서에 따르면 값은 none, main, exec, all 중 하나다.
| 값 | 허용 범위 | 무난한 사용 상황 |
|---|---|---|
main |
메인 프로세스만 허용 | 주 프로세스가 직접 READY=1을 보내는 일반적인 경우 |
exec |
Exec*=로 시작된 main/control 프로세스 허용 |
control process도 상태 통지를 해야 할 때 |
all |
같은 cgroup의 모든 프로세스 허용 | 보조 프로세스가 통지를 보내야 하지만 구조를 바꾸기 어려울 때 |
중요한 점은 공식 문서가 Type=notify 또는 WatchdogSec=를 사용할 때 NotifyAccess=를 열어 두라고 설명한다는 것이다. 값을 따로 적지 않거나 none이면 systemd가 강제로 main으로 바꾼다.
또한 sd_notify 문서는 보조 프로세스가 메시지를 보낸 직후 바로 종료하면, 심지어 NotifyAccess=all이어도 systemd가 해당 메시지를 유닛에 제대로 귀속시키지 못해 무시할 수 있다고 설명한다. 따라서 메인 프로세스나 systemd가 직접 시작한 프로세스가 통지하도록 설계하는 편이 안전하다.
sd_notify()로 무엇을 보낼 수 있을까?
가장 기본적인 메시지는 READY=1이다. upstream sd_notify 문서에 따르면 이 값은 서비스 시작 완료 또는 reload 완료를 알릴 때 쓰이며, READY=0 같은 값은 정의돼 있지 않다.
STATUS=...를 함께 보내면 systemctl status 같은 곳에 사람이 읽을 수 있는 상태 문자열을 남길 수 있다. reload를 추적해야 하면 Type=notify-reload와 함께 RELOADING=1, MONOTONIC_USEC=..., 그리고 reload 완료 후 다시 READY=1을 보내는 흐름을 쓴다.
watchdog를 켠 서비스는 주기적으로 WATCHDOG=1을 보내 keep-alive를 갱신한다. 서비스가 내부 오류를 감지했고 watchdog 동작으로 처리하고 싶다면 WATCHDOG=trigger도 보낼 수 있다.
운영에서 무난한 선택 기준은 어떻게 잡을까?
| 상황 | 무난한 선택 | 이유 |
|---|---|---|
| 실행 파일 존재와 권한 문제만 잡으면 되는 일반 데몬 | Type=exec |
실행 준비 실패를 명확히 잡고 설정이 단순함 |
| 포트 바인딩, 캐시 준비, 초기 동기화 이후에만 준비 완료로 봐야 하는 데몬 | Type=notify + NotifyAccess=main |
서비스 코드가 정확한 readiness 시점을 통지할 수 있음 |
| reload 완료까지 systemd가 추적해야 하는 서비스 | Type=notify-reload |
reload 시작과 완료를 상태 메시지로 표현 가능 |
| 기존 daemonize 방식과 PID 파일 의존성이 남아 있는 서비스 | Type=forking |
레거시 호환 목적, 다만 신규 설계의 기본값으로 보기는 어려움 |
핵심은 Type=notify가 더 "좋은" 타입이라기보다, readiness를 서비스가 스스로 선언해야 할 때 필요한 타입이라는 점이다. 준비 완료의 기준을 코드 안에서 정의하지 못한다면 오히려 운영 복잡도만 늘어난다.
자주 헷갈리는 질문
Q. 장기 실행 서비스면 항상 Type=notify가 더 나을까?
그렇게 보기 어렵다. 공식 문서는 장기 실행 서비스의 일반적인 권장값으로 Type=exec를 설명한다. notify는 readiness를 코드가 정확히 선언할 필요가 있을 때 선택하는 쪽에 가깝다.
Q. NotifyAccess=all로 두면 가장 안전할까?
항상 그렇지는 않다. 허용 범위를 넓히는 대신 어떤 프로세스가 상태 통지를 보냈는지 추적이 어려워질 수 있고, 보조 프로세스가 바로 종료하면 귀속 race가 남을 수 있다. 메인 프로세스가 직접 보내는 구조라면 main이 더 단순하다.
Q. reload도 같은 방식으로 처리할 수 있을까?
가능하다. 다만 공식 문서는 reload 추적이 필요하면 일반 notify보다 notify-reload를 권장한다. 이 경우 reload 시작 시 RELOADING=1과 MONOTONIC_USEC=..., 완료 시 READY=1을 보내야 한다.
정리
Type=exec는 실행 준비 단계의 오류를 정확히 잡는 기본값이고, Type=notify는 서비스 코드가 readiness를 선언해야 할 때 쓰는 선택지다. 대부분의 서비스는 먼저 exec를 기준으로 생각하고, 실제 준비 완료 시점을 외부에 알려야 할 이유가 분명할 때만 notify로 올리는 편이 안전하다.
2026년 6월 22일 기준 upstream systemd 공식 문서를 기준으로 보면, Type=notify를 도입할 때 같이 확인해야 할 핵심은 세 가지다. READY=1을 언제 보낼지, 누가 보낼지에 맞는 NotifyAccess= 값이 무엇인지, 그리고 reload나 watchdog까지 같은 채널로 다룰지다.
참고 자료
'프로그래밍 > 운영체제' 카테고리의 다른 글
| systemd override.conf 사용법 (1) | 2026.07.05 |
|---|---|
| systemd ExecCondition 기준 정리 (1) | 2026.06.27 |
| systemd Restart 정책 기준 정리 (0) | 2026.06.15 |
| systemd RuntimeDirectory와 StateDirectory 기준 정리 (0) | 2026.06.09 |
| 리눅스 tmpfiles.d 설정 기준 정리 (0) | 2026.05.28 |





