이전시리즈 보기
Nest.js 라이프사이클 완전 정복 (1/3)- 모듈 초기화 단계(Initialization Phase)
Nest.JS를 사용하다보면 서비스나 모듈이 언제 생성되고 언제 실행되는지 모를때가 있습니다. 그런 경험이 있다면 Nest.js의 라이프 사이클을 잘 모르기 때문일거라 생각합니다.그렇다면 과연 Nest.j
gapal.tistory.com
NestJS 라이프사이클 (2/3): 가드, 파이프, 인터셉터! 요청이 Controller를 통과하는 7단계
이전 포스팅에서 onModuleInit()으로 초기 설정이 끝났으며 Nest.js에서 모듈 초기화가 끝났으면 다음 단계로 넘어가게 됩니다!(모듈 초기화 과정)https://gapal.tistory.com/71 Nest.js 라이프사이클 완전 정복
gapal.tistory.com

종료단계 (Termination)
Nest.js의 라이프사이클 중 3단계인 종료 단계는 어플리케이션이 안전하게 종료되는 과정을 다룹니다.
이 단계는 운영환경에서 서버가 재배포되거나 유지보수를 위해서 중단될 때 작업 중이거나 진행 중이던 요청사항을 완료하고
사용 중이던 시스템 리소스를 정리할 수 있도록 합니다.
이 단계에서 호출되는 3가지의 훅이 있는데 종류는 아래와 같습니다.
종료 훅
1.onModuleDestory()
- 호출 시점: 애플리케이션이 SIGTERM과 같은 종료 신호를 받은 직후, 모든 모듈과 그 안의 서비스들에서 호출됩니다.
- 주요 역할: 모듈 수준의 리소스 정리입니다. 각 모듈이 자체적으로 관리하던 연결이나 타이머 등을 닫습니다.
- 특징: 모든 모듈의 onModuleDestroy()가 병렬적으로 실행되지만, 다음 단계로 넘어가기 전에 모두 완료되어야 합니다.
- 사용예시: 데이터베이스 연결 풀 해제, Redis 클라이언트 연결 해제, 설정된 setInterval()이나 setTimeout() 클리어.
2.beforeApplicationShutdown()
- 호출 시점: 모든 onModuleDestroy() 훅이 완료된 후, 외부 요청을 받는 리스너(HTTP 서버 등)가 닫히기 직전에 호출됩니다.
- 주요 역할: 애플리케이션 전체 수준에서 최종 정리를 수행할 수 있는 마지막 기회입니다. 이 시점까지는 아직 진행 중인 요청을 처리할 수 있습니다.
- 사용예시: 로깅 시스템의 버퍼를 플러시(flush)하거나, 중요한 최종 상태를 외부 시스템에 저장.
3. onApplicationShutdown()
- 호출 시점: HTTP 서버와 같은 모든 리스너와 연결이 완전히 닫힌 후, 즉, 애플리케이션이 외부 요청을 더 이상 처리할 수 없을 때 호출됩니다.
- 주요 역할: 애플리케이션의 종료 완료를 알리고, 더 이상 외부 의존성이 필요 없는 마무리 작업을 수행합니다.
- 사용예시: 최종 정리 상태를 로깅하거나, 종료 프로세스가 완료되었음을 알림.
코드
app.service.ts
main.ts
app.module.ts
app.controller.ts
출력결과

위처럼 출력결과를 보게되면 onModuleDestory가 호출된 다음에
beforeApplicationShutdown 그리고 onApplicationShutdown이 순서대로 호출되는데
이때 시그널을 보면 SIGINT로 호출되는 모습을 볼수 있습니다.
이 시그널 값은 사용자가 어떤 형식으로 애플리케이션을 종료는 지에 따라 값이 다르게 되는데 그 값의 종류는 아래와 같습니다.
시그널 종류
| 시그널 이름 | 설명 | NestJS/Node.js 처리 방식 |
| SIGINT | 인터럽트 (Interrupt).터미널에서 Ctrl + C 를 눌렀을 때 발생합니다. | 기본적으로 NestJS에서Graceful Shutdown을 시작하는 시그널입니다. |
| SIGTERM | 종료 요청 (Terminate).가장 일반적인프로그램 종료 요청 시그널입니다. | Kubernetes, Docker kill <PID> 명령어가 보내는 시그널로, NestJS에서 Graceful Shutdown을 시작합니다. |
| SIGHUP | 행업 (Hang up).보통 터미널 연결이 끊어지거나, 부모 프로세스가 종료될 때 발생합니다. | 과거에는 종료를 의미했지만, 종종설정 파일 다시 로드를 요청하는 용도로 사용되기도 합니다. NestJS에서는 처리 로직을 추가해야 합니다. |
| SIGQUIT | 종료 및 코어 덤프 (Quit).코어 덤프 파일을 생성하여 디버깅 정보를 남깁니다. 터미널에서 Ctrl + \ 를 눌러 발생시킵니다. | SIGTERM처럼 Graceful Shutdown을 시작하도록 설정할 수 있습니다. |
| SIGKILL | 강제 종료 (Kill). 프로세스가 무시하거나 가로챌 수 없는 시그널입니다. | 프로세스를 즉시 종료시킵니다. NestJS의 3단계 훅(onModuleDestroy 등)이 호출되지 않고 비정상적으로 종료됩니다. |
위처럼 각 시그널별로 특정한 상황에 인자값이 다르므로 해당 동작일때만의 예외처리나 로직을 작성할 때는 위 시그널 값을 통해서 로직을 작성하면 됩니다.
enableShutdownHooks() 의 역할
제일 중요한 대목 중 하나가 enableShutdownHooks()입니다.
Main.ts에 있는 enableShutdownHooks는 NestJS 애플리케이션이 운영체제(OS)로부터의 종료 신호를 감지하고, 이에 반응하여 우아한 종료(Graceful Shutdown) 프로세스를 시작하도록 활성화하는 것입니다.
즉 이 함수가 없으면 Nest.js가 외부의 종료명령에 따라 훅들을 실행하는데 위 코드가 없으면 아무것도 실행되지 않고 바로 강제 종료가 발생하게 됩니다.
요약하자면, enableShutdownHooks()는 NestJS에게 "외부에서 종료하라고 하면, 3단계 종료 훅을 실행해서 깔끔하게 정리하고 끝내라"라고 명령하는 스위치라고 이해하시면 됩니다.
NestJS의 종료 단계는 단순한 종료 명령을 넘어, SIGTERM을 포착하여 비동기 정리 작업을 순차적으로 완료하고 연결을 안전하게 닫는 Graceful Shutdown의 정수를 보여줍니다. 이 3단계 훅의 이해는 프로덕션 환경에서 안정적이고 견고한 애플리케이션을 운영하기 위한 필수 관문입니다.
이 코드들의 동작원리와 행동을 이해하면 더욱 깊이 있는 코드를 작성할 수 있습니다.
'TypeScript > Nest.js' 카테고리의 다른 글
| NestJS 커스텀 데코레이터 만들기: 로그(@LogTest) 기능 구현 예제 (0) | 2025.12.03 |
|---|---|
| NestJS 라이프사이클 (2/3): 가드, 파이프, 인터셉터! 요청이 Controller를 통과하는 7단계 (0) | 2025.11.25 |
| Node.js tsconfig esModuleInterop allowSyntheticDefaultImports 설정 완벽하게 알아보기 (0) | 2025.11.21 |
| Node.js 모듈 시스템 완벽 정리: CJS vs. ESM 파헤쳐보기 (0) | 2025.11.20 |
| NestJS Swagger JWT 인증 설정 방법 | 전역 보안 적용 가이드 (2) | 2025.11.15 |
