19. 수명 주기 이벤트

Nest 애플리케이션과 모든 애플리케이션 요소에는 Nest에서 관리하는 수명 주기가 있다. Nest는 주요 수명 주기 이벤트에 대한 가시성과 이벤트 발생 시 조치(모듈, 공급자 또는 컨트롤러에 등록된 코드 실행) 기능을 제공하는 수명 주기 훅을 제공한다.

 

수명 주기 순서

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

수명 주기 이벤트

수명 주기 이벤트는 애플리케이션 부트스트래핑 및 종료 중에 발생한다. Nest는 다음 각 수명 주기 이벤트에서 모듈, 공급자 및 컨트롤러에 등록된 수명 주기 후크 메서드를 호출한다( 아래 설명과 같이 종료 후크를 먼저 활성화해야 함 ). 위 다이어그램에 표시된 것처럼 Nest는 연결 수신을 시작하고 연결 수신을 중지하기 위해 적절한 기본 메서드도 호출한다.

 

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

수명주기 후크 방법후크  메서드 호출을 트리거하는 수명 주기 이벤트
onModuleInit() 호스트 모듈의 종속성이 해결되면 호출된다.
onApplicationBootstrap() 모든 모듈이 초기화된 후 호출되지만 연결을 수신하기 전에 호출된다.
onModuleDestroy()* 종료 신호(예: SIGTERM)가 수신된 후 호출된다.
beforeApplicationShutdown()* 모든 onModuleDestroy()핸들러가 완료된 후 호출된다(프로미스가 해결 또는 거부됨).
완료되면(프라미스가 해결되거나 거부됨) 기존의 모든 연결이 닫힙니다( app.close() 호출됨).
onApplicationShutdown()* 연결이 닫힌 후 호출됩니다( app.close() 수행).

 

이러한 이벤트의 경우 명시적으로 app.close() 을 호출하지 않는 경우 SIGTERM 와 같은 시스템 신호와 함께 작동하도록 선택해야한다. 아래의 애플리케이션 종료를 참조하자.

 

주위) 위에 나열된 수명 주기 후크는 요청 범위 클래스에 대해 트리거되지 않는다. 요청 범위 클래스는 애플리케이션 수명 주기에 묶여 있지 않으며 수명을 예측할 수 없다. 각 요청에 대해 독점적으로 생성되며 응답이 전송된 후 자동으로 가비지 수집되기 때문이다.

 

힌트 ) onModuleInit() 와 onApplicationBootstrap() 의 실행 순서는 이전 후크를 기다리는 모듈 가져오기 순서에 직접적으로 의존한다.

 

사용법

각 수명 주기 후크는 인터페이스로 표시됩니다. 인터페이스는 TypeScript 컴파일 후에는 존재하지 않기 때문에 기술적으로 선택 사항이다. 그럼에도 불구하고 강력한 타이핑 및 편집기 도구의 이점을 얻으려면 이를 사용하는 것이 좋다. 수명 주기 후크를 등록하려면 적절한 인터페이스를 구현해야한다. 예를 들어 특정 클래스(예: Controller, Provider 또는 Module)에서 모듈 초기화 중에 호출할 메서드를 등록하려면 아래와 같이 OnModuleInit 인터페이스를 구현한 onModuleInit() 메서드를 제공하여야한다.

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

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}

 

비동기 초기화

OnModuleInit 및 OnApplicationBootstrap 훅을 사용하면 애플리케이션 초기화 프로세스를 연기할 수 있다( Promise 메소드를 반환하거나 비동기 메서드 본문에 async 혹은 await 구문이 있을경우)

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

 

어플리케이션 종료

onModuleDestroy(),  beforeApplicationShutdown()onApplicationShutdown() 훅은  종료 단계에서 호출된다( SIGTERM과 같은 시스템 신호를 수신하거나 명시적인 app.close() 호출에 대한 응답으로) . 이 기능은 Heroku 에서 dynos 또는 유사한 서비스를 위해 컨테이너의 수명 주기를 관리하기 위해 Kubernetes 와 함께 자주 사용된다 .

 

종료 후크 수신기는 시스템 리소스를 소비하므로 기본적으로 비활성화되어 있다. 종료 후크를 사용하려면 enableShutdownHooks() 호출하여 리스너를 활성화 해야한다.

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

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

  // Starts listening for shutdown hooks
  app.enableShutdownHooks();

  await app.listen(3000);
}
bootstrap();

힌트) enableShutdownHooks로 인해 시작된 리스너는 메모리를 소비한다. 단일 Node 프로세스에서 여러 Nest 앱을 실행하는 경우(예: Jest로 병렬 테스트를 실행하는 경우) Node는 과도한 리스너 프로세스에 대해 불평할 수 있다. 이러한 이유로 enableShutdownHooks기본적으로 활성화되어 있지 않는다. 단일 노드 프로세스에서 여러 인스턴스를 실행하는 경우 이 조건에 유의하자.

 

애플리케이션이 종료 신호를 수신하면 해당 신호를 첫 번째 매개변수로 사용하여 등록된 onModuleDestroy(), beforeApplicationShutdown(), onApplicationShutdown() 메소드를 순서대로 호출한다. 등록된 함수가 비동기 호출(Promise 반환)을 기다리는 경우 Nest는 Promise가 해결되거나 거부될 때까지 시퀀스를 계속하지 않는다.

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

힌트) app.close() 호출은 Node 프로세스를 종료하지 않고  onModuleDestroy() 및  onApplicationShutdown() 훅만 트리거하므로 일정간격, 장기 실행 백그라운드 작업 등이 있는 경우 프로세스가 자동으로 종료되지 않는다.

'Backend(Framework) > NestJS 개요(공식문서 번역)' 카테고리의 다른 글

20. 테스트  (1) 2023.12.10
18. Execution context  (1) 2023.12.02
17. Lazy-loading modules  (1) 2023.12.02
16. Module reference  (1) 2023.12.02
15. Circular Dependency  (1) 2023.12.02
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유