[Nestjs] microserivce 쓸 때 중복 반환 해결법
nestjs 에서 mqtt를 사용할 때 주의해야할 점이 있습니다.
공식문서에서 MicroService를 사용해서 redis나 mqtt 등을 사용하려고 하면
overView로 아래 코드블럭을 보여줍니다.
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.TCP,
},
);
await app.listen();
}
bootstrap();
이 코드블럭에는 치명적인 문제가 있습니다.
🟥 문제 코드
async function bootstrap() {
// 1. http서버로 사용
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
cors: true,
logger: winstonLogger,
});
const port = process.env.PORT || 3000;
console.log(
`main server start port : ${port} mqtt: ${process.env.MQTT_HOST}`,
);
const mqttApp = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.MQTT,
preview: true,
options: {
url: `mqtt://${process.env.MQTT_HOST}:${process.env.MQTT_PORT}`,
// keepalive: 30000,
reconnectPeriod: 3000,
},
},
);
await mqttApp.listen();
await app.listen(port);
}
bootstrap();
처음에 저는 이렇게 썼었습니다.
"아 ~ NestFactory로 microService를 주입하는 거구나~" 라는 생각을 가지고 있었죠.
하지만 nest는 NestFactory를 만나면 또 다른 Nest 컨테이너를 생성하는 겁니다.
그런데 이걸 왜 지금까지 발견을 못했느냐. microService는 Http 요청 처리를 안하기 때문입니다.
그렇기 때문에 mqtt, redis 같은 tcp만 잡아서 처리를 하니 mqtt, redis 요청을 테스트할 때 유심히 보지 않으면 쿼리가 2번 나가는 것을 확인하기 힘듭니다.
🟩 해결방법
공식문서에 답이 있었습니다.
const app = await NestFactory.create(AppModule);
const microservice = app.connectMicroservice<MicroserviceOptions>({
transport: Transport.TCP,
});
await app.startAllMicroservices();
await app.listen(3001);
app에 MicroService(mqtt, redis... 등등)을 넣고 싶다면 connectMicroService를 이용하라고 하네요.
🟦 변화된 코드
declare const module: any;
dotenv.config();
async function bootstrap() {
// 1. http서버로 사용
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
cors: true,
logger: winstonLogger,
});
const port = process.env.PORT || 3000;
console.log(`main server start port : ${port} mqtt: ${process.env.MQTT_HOST}`);
app.connectMicroservice<MicroserviceOptions>({
transport: Transport.MQTT,
options: {
url: `mqtt://${process.env.MQTT_HOST}:${process.env.MQTT_PORT}`,
// keepalive: 30000,
reconnectPeriod: 3000,
},
});
// const mqttApp = await NestFactory.createMicroservice<MicroserviceOptions>(
// AppModule,
// {
// transport: Transport.MQTT,
// preview: true,
// options: {
// url: `mqtt://${process.env.MQTT_HOST}:${process.env.MQTT_PORT}`,
// // keepalive: 30000,
// reconnectPeriod: 3000,
// },
// },
// );
// await mqttApp.listen();
await app.startAllMicroservices();
await app.listen(port);
}
bootstrap();
하나의 NestFactory안에서 mqtt도 받을 수 있게되었습니다.
🙏
Nest 공식문서를 잘 봐야겠다는 생각이 들었습니다.
이 Hybrid application 이라는 생소한 탭에 내가 원하는 정보가 있다는 것을 믿을 수 없었습니다.
내가 원하는 상황, 현상의 이름을 영어로 잘 풀어쓰는 것이 중요하다고 깨달았습니다. 근데 영어를 안다고 해서 hybrid application을 떠올릴 수 있을까 의문이 들긴 합니다.