본문 바로가기

웹/Nest

[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을 떠올릴 수 있을까 의문이 들긴 합니다.

 

 

 

 

 

 

 

728x90