[Nest.js] graceful shutdown을 구현하자.
2022. 6. 12. 16:31ㆍ개발/Node & Javascript
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
반응형
'개발 > Node & Javascript' 카테고리의 다른 글
[RXJS] Hot Observable vs Cold Observable (2) | 2022.07.10 |
---|---|
[RXJS] from vs of 차이 (3) | 2022.06.27 |
[RxJS] bufferCount 써보기 (0) | 2022.05.08 |
[RxJS] Promise.all 대신 mergeMap 써보기 (0) | 2022.05.08 |
JS - flame graph로 cpu profiling (1) | 2022.04.24 |