개발/Node & Javascript

[Nest.js] graceful shutdown을 구현하자.

말고기 2022. 6. 12. 16:31
728x90
반응형

개요

  • nest.js에서는 여러 lifecycle-events를 제공한다.
  • 이중에서 shutdown events를 활용해서 graceful shutdown을 구현해보자.

어떨 때 사용할까?

  • 일반적으로 graceful shutdown을 구현할 때 사용한다.
  • consumer는 consume을 중단하고, 현재 남아있는 작업을 처리할 동안 대기한다.
  • log의 경우 buffer에 남아있는 log를 처리하고 종료를 진행한다.

예제

  • 아래의 예제는 log를 buffer에만 쌓아두다가 종료시 한 번에 처리하는 형태로 예제를 구성해보았다.

1. logger 생성

interface BufferLogFormat {
  level: string;
  message: string;
}

// 극단적인 상황을 가정하기 위해서, buffer에만 쌓는다.
@Injectable()
export class CustomBufferLogger
  implements LoggerService, OnApplicationShutdown
{
  private readonly buffer: BufferLogFormat[] = [];

  async onApplicationShutdown(signal?: string) {
    this.warn(`Received signal ${signal}`);
    await this.end();
    console.log('Logging closed');
  }

  private end(): Promise<void> {
    console.log(JSON.stringify(this.buffer));
  }

  error(message: any, ...optionalParams: any[]): any {
    this.buffer.push({ level: 'error', message });
  }

  log(message: any, ...optionalParams: any[]): any {
    this.buffer.push({ level: 'log', message });
  }

  warn(message: any, ...optionalParams: any[]): any {
    this.buffer.push({ level: 'warn', message });
  }
}

2. shutdown hook 활성화

// bootstrap

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});

app.useLogger(app.get(CustomBufferLogger));
app.enableShutdownHooks();

await app.listen(3000);

3. Test

# start application
yarn start

# kill with SIGTERM
kill -15  $(lsof -i tcp:3000 |  awk '{if (NR > 1) print $2 }')

# start application2
yarn start

# kill with SIGKILL, 로그가 남지 않음
kill -9  $(lsof -i tcp:3000 |  awk '{if (NR > 1) print $2 }')

SIGTERM 그리고 SIGKILL

  • SIGTERM은 graceful shutdown을 요청할 때 사용한다.
  • 일반적인 환경에서는 SIGTERM을 주고 일정 시간 이후 종료되지 않는 경우에는 SIGKILL을 보낸다.

주의사항

  • SIGTERM 이외에도 다양한 signal을 처리할 수 있도록 지원하고 있다.
  • 일반적으로 정상적인 종료 상황에서는 SIGTERM을 통해서 종료 작업이 될 수 있지만 일부 비정상적인 종료 상황에서는 처리를 못할수도 있다.
  • 보통 SIGTERM 이후 SIGKILL을 보내기 때문에 timeout 구현을 통해 적절히 핸들링 해주는 것이 좋다.

출처

728x90
반응형