NestJS Lifecycle Events
그동안 1년정도 블로그를 쉬었던 것 같네요.
공부하고 그 내용을 정리해서 블로그에 올리는게 막상 쉽지는 않네요.
이제 다시 블로그에 올려보도록 하겠습니다. 혼자 하는 정리는 본인만 보는거라 부담이 없지만 블로그에 올리는건 다른 사람들도 볼 수 있는거라 더 부담이 크네요. 다시 홧팅!
- lifecycle events가 무엇인지 3줄 설명
- lifecycle 순서 설명 - 각 단계에 대해서 1줄 설명
- event 설명
- 내가 kafka 연결하면서 사용했던 예시 적기
Lifecycle Events
NestJS에 생명주기 이벤트들 입니다.
어플리케이션은 실행될 때, 종료 될 때 등등 어플리케이션 수명과 관련된 이벤트를 발생시킵니다.
그리고 NestJS에서 이벤트가 발생했을 때 실행할 동작들을 정의할 수 있습니다.
onModuleInit이라는 이벤트가 발생될 때 'Hello UserService'를 출력하겠다고 정의했습니다.
import { Injectable, OnModuleInit } from '@nestjs/common';
@Injectable()
export class UsersService implements OnModuleInit {
onModuleInit() {
console.log('Hello UserService');
}
}
Lifecycle sequence
Lifecycle 공부를 하다보면 많이 보셨을 그림입니다.
생명주기는 크게 시작, 실행, 종료 부분으로 나눌 수 있습니다.
Lifecycle events
생명주기 hook 메서드 | hook 메서드를 트러기하는 생명주기 이벤트 |
onModuleInit() | host 모듈의 종속성이 해결되면 호출 됩니다. (어플리케이션에 있어서 1회 호출) |
onApplicationBootstrap() | 모든 모듈이 초기화 된 다음 connection을 수신 대기 할 때 호출됩니다.(어플리케이션에 있어서 1회 호출) |
onModuleDestroy()* | 종료 신호(ex. SIGTERM) 가 호출되고 나서 실행됩니다. |
beforeApplicationShutdown()* | onModuleDestroy()가 완료되고 나서 호출됩니다. 기존 모든 연결이 닫힙니다. (app.close() 호출) |
onApplicationShutdown()* | 연결이 종료된 후 호출됩니다. app.close()가 해결 |
* 표시가 있는 hook 메소드들은 사용을 위해서는 아래와 같이 작성해 줘야합니다.
shutdown hook listner는 시스템 리소스를 사용하므로 기본적으로 비활성화 되어있습니다.
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();
WARNING
NestJS에서 shutdown hook을 제한적으로 지원합니다.
더 자세한것을 알고싶으면 https://nodejs.org/api/process.html#process_signal_events 링크를 통해주세요.
실제 사용 코드
제가 NestJS microservice 모듈을 이용해 kafka를 연결했을 때 사용한 코드입니다.
onModuleInit() 메서드를 오버라이딩하여 모듈의 종석성이 해결될 때 ClientKafka와 연결시켰습니다.
또 onModuleDestroy() 메서드를 이용해 어플리케이션에 종료 신호가 수신되었을 때 kafka connection을 닫도록 했습니다.
import {Controller, Get, Inject, OnModuleDestroy, OnModuleInit} from '@nestjs/common';
import { AppService } from './app.service';
import { ClientKafka } from '@nestjs/microservices';
@Controller()
export class AppController implements OnModuleInit, OnModuleDestroy{
constructor(
private readonly appService: AppService,
@Inject('any_name_i_want') private readonly client: ClientKafka,
) {}
async onModuleInit() {
['medium.rocks'].forEach((key) => this.client.subscribeToResponseOf(`${key}`));
await this.client.connect(); // message가 비동기적으로 생성되면 connect하기 전 subscribeToResponseOf()함수를 호출해야합니다.
}
async onModuleDestroy() {
await this.client.close();
}
@Get('kafka-test')
testKafka(){
const a = this.client.emit('medium.rocks', {foo:'bar', data: new Date().toString()})
}
@Get('kafka-test-with-response')
testKafkaWithResponse(){
return this.client.send('medium.rocks', {foo:'bar', data: new Date().toString()})
}
}