NestJS Logo

라이프사이클 이벤트

Nest 애플리케이션과 모든 애플리케이션 요소는 Nest에 의해 관리되는 라이프사이클을 가집니다. Nest는 주요 라이프사이클 이벤트에 대한 가시성과 해당 이벤트 발생 시 작동(모듈, 프로바이더 또는 컨트롤러에 등록된 코드를 실행)할 수 있는 기능인 라이프사이클 훅을 제공합니다.

라이프사이클 순서#

다음 다이어그램은 애플리케이션이 부트스트랩되는 시점부터 Node 프로세스가 종료될 때까지의 주요 애플리프레이션 라이프사이클 이벤트 순서를 보여줍니다. 전체 라이프사이클은 세 단계로 나눌 수 있습니다: 초기화, 실행, 종료. 이 라이프사이클을 사용하여 모듈 및 서비스의 적절한 초기화를 계획하고, 활성 연결을 관리하며, 종료 신호를 받을 때 애플리케이션을 정상적으로 종료할 수 있습니다.

라이프사이클 이벤트#

라이프사이클 이벤트는 애플리케이션 부트스트랩 및 종료 중에 발생합니다. Nest는 다음 각 라이프사이클 이벤트 발생 시 모듈, 프로바이더 및 컨트롤러에 등록된 라이프사이클 훅 메서드를 호출합니다 (종료 훅아래 설명된 대로 먼저 활성화해야 합니다). 위 다이어그램에 표시된 것처럼 Nest는 연결 수신을 시작하고 연결 수신을 중지하기 위해 적절한 내부 메서드도 호출합니다.

다음 표에서 onModuleInitonApplicationBootstrapapp.init() 또는 app.listen()을 명시적으로 호출한 경우에만 트리거됩니다.

다음 표에서 onModuleDestroy, beforeApplicationShutdownonApplicationShutdownapp.close()를 명시적으로 호출하거나 프로세스가 특수 시스템 신호(예: SIGTERM)를 수신하고 애플리케이션 부트스트랩 시 enableShutdownHooks를 올바르게 호출한 경우에만 트리거됩니다(아래 애플리케이션 종료 부분 참고).

라이프사이클 훅 메서드라이프사이클 이벤트 트리거
onModuleInit()호스트 모듈의 종속성이 해결된 후 한 번 호출됩니다.
onApplicationBootstrap()모든 모듈이 초기화되었지만 연결 수신을 시작하기 전에 한 번 호출됩니다.
onModuleDestroy()*종료 신호(예: SIGTERM)가 수신된 후 호출됩니다.
beforeApplicationShutdown()*모든 onModuleDestroy() 핸들러가 완료된 후(Promises가 해결 또는 거부됨) 호출됩니다.
완료되면(Promises가 해결 또는 거부됨) 모든 기존 연결이 닫힙니다(app.close() 호출).
onApplicationShutdown()*연결이 닫힌 후(app.close()가 해결됨) 호출됩니다.

* 이 이벤트들의 경우, app.close()를 명시적으로 호출하지 않는다면 SIGTERM과 같은 시스템 신호와 함께 작동하도록 옵트인(opt-in)해야 합니다. 아래 애플리케이션 종료를 참조하십시오.

경고 위에 나열된 라이프사이클 훅은 요청 스코프 클래스에 대해서는 트리거되지 않습니다. 요청 스코프 클래스는 애플리케이션 라이프사이클에 묶여 있지 않으며 수명이 예측 불가능합니다. 이들은 각 요청마다 독점적으로 생성되며 응답이 전송된 후 자동으로 가비지 수집됩니다.
onModuleInit()onApplicationBootstrap()의 실행 순서는 이전 훅을 기다리는 모듈 import 순서에 직접적으로 의존합니다.

사용법#

각 라이프사이클 훅은 인터페이스로 표현됩니다. 인터페이스는 TypeScript 컴파일 후에는 존재하지 않기 때문에 기술적으로는 선택 사항입니다. 그럼에도 불구하고 강력한 타입 지정 및 에디터 도구의 이점을 얻기 위해 사용하는 것이 좋습니다. 라이프사이클 훅을 등록하려면 적절한 인터페이스를 구현하십시오. 예를 들어, 특정 클래스(예: Controller, Provider 또는 Module)에서 모듈 초기화 중에 호출될 메서드를 등록하려면 아래에 표시된 것처럼 onModuleInit() 메서드를 제공하여 OnModuleInit 인터페이스를 구현하십시오.

JS TS

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`모듈이 초기화되었습니다.`);
  }
}

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`모듈이 초기화되었습니다.`);
  }
}

비동기 초기화#

OnModuleInitOnApplicationBootstrap 훅 모두 애플리케이션 초기화 프로세스를 지연시킬 수 있습니다(Promise를 반환하거나 메서드를 async로 표시하고 메서드 본문에서 비동기 메서드 완료를 await함).

JS TS

async onModuleInit(): Promise<void> {
  await this.fetch();
}

async onModuleInit() {
  await this.fetch();
}

애플리케이션 종료#

onModuleDestroy(), beforeApplicationShutdown(), onApplicationShutdown() 훅은 종료 단계에서 호출됩니다(app.close()에 대한 명시적 호출에 응답하거나 옵트인된 경우 SIGTERM과 같은 시스템 신호를 수신하면). 이 기능은 컨테이너 라이프사이클 관리를 위해 Kubernetes에서, dyno 관리를 위해 Heroku에서 또는 유사한 서비스에서 자주 사용됩니다.

종료 훅 리스너는 시스템 리소스를 소비하므로 기본적으로 비활성화되어 있습니다. 종료 훅을 사용하려면 enableShutdownHooks()를 호출하여 리스너를 활성화해야 합니다 :


import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 종료 훅 수신 시작
  app.enableShutdownHooks();

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
경고 플랫폼의 내재된 제한으로 인해 NestJS는 Windows에서 애플리케이션 종료 훅에 대한 지원이 제한적입니다. SIGINTSIGBREAK는 작동할 것으로 예상되며, 어느 정도 SIGHUP도 작동할 수 있습니다 - 더 읽어보기. 그러나 작업 관리자에서 프로세스를 종료하는 것은 무조건적이기 때문에("즉, 애플리케이션이 이를 감지하거나 방지할 방법이 없음") Windows에서는 SIGTERM이 절대로 작동하지 않습니다. SIGINT, SIGBREAK 등이 Windows에서 어떻게 처리되는지에 대해 더 알아보려면 libuv의 관련 문서를 참조하십시오. 또한 Node.js의 Process Signal Events 문서도 참조하십시오.
정보enableShutdownHooks는 리스너를 시작하여 메모리를 소비합니다. 단일 Node 프로세스에서 여러 Nest 앱을 실행하는 경우(예: Jest로 병렬 테스트 실행 시) Node가 과도한 리스너 프로세스에 대해 불평할 수 있습니다. 이러한 이유로 enableShutdownHooks는 기본적으로 활성화되어 있지 않습니다. 단일 Node 프로세스에서 여러 인스턴스를 실행하는 경우 이 조건을 유의하십시오.

애플리케이션이 종료 신호를 수신하면 등록된 onModuleDestroy(), beforeApplicationShutdown(), 그 다음 onApplicationShutdown() 메서드(위에 설명된 순서대로)를 해당 신호를 첫 번째 매개변수로 사용하여 호출합니다. 등록된 함수가 비동기 호출(Promise 반환)을 기다리는 경우, Nest는 해당 Promise가 해결 또는 거부될 때까지 순서를 계속 진행하지 않습니다.

JS TS

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // 예: "SIGINT"
  }
}

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal) {
    console.log(signal); // 예: "SIGINT"
  }
}
정보app.close()를 호출하는 것은 Node 프로세스를 종료시키지 않고 onModuleDestroy()onApplicationShutdown() 훅만 트리거합니다. 따라서 일부 인터벌, 장시간 실행되는 백그라운드 작업 등이 있는 경우 프로세스는 자동으로 종료되지 않습니다.

Support us

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more here.

Principal Sponsors

Trilon LogoMojam Logo

Sponsors / Partners

Become a sponsor