본문 바로가기

카테고리 없음

[NestJs] microservice RabbitMQ 적용 - (적용)

반응형

이전 글에서 NestJs에서 microservice-RabbitMQ 개념을 설명했습니다.

RabbitMQ은 docker을 통해 띄웠는데, 다른글 참조해주세요. 

 


 

0. RMQ_URL과 RMQ_QUE

// ex: amqp://guest:guest@localhost:5672
// RMQ 최초 아이디/비밀번호는 guest/guest
RMQ_URL = amqp://{rmq id}:{rmq pw}@{host}:{port}

// ex: hellow
RMQ_QUE = que name

1. main.ts에서 microservice start

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const configService = app.get(ConfigService);

  const microservice = app.connectMicroservice({
    transport: Transport.RMQ,
    options: {
      urls: ["RMQ_URL"],
      queue: "RMQ_QUE",
      queueOptions: {
        durable: false,
      },
    },
  });

  await app.startAllMicroservices();
  await app.listen(process.env.PORT);
}
bootstrap();

 

2. module에서 import

export const RMQConfig = ClientsModule.registerAsync([
  {
    name: "RMQ_SERVICE",
    imports: [ConfigModule],
    useFactory: (configService: ConfigService) => ({
      transport: Transport.RMQ,
      options: {
        urls: [configService.get<string>("RMQ_URL")],
        queue: configService.get<string>("RMQ_QUE"),
        queueOptions: {
          durable: false,
        },
      },
    }),
    inject: [ConfigService],
  },
]);

RMQ_SERVICE를 기억하자. 그리고 .env값을 사용하기 위해, register대신 registerAsync를 사용했다.

 

3. Inject(name)으로 접근

export class APPCLASS {
  constructor(
    private readonly appService: AppService,
    @Inject("RMQ_SERVICE") private rmqClient: ClientProxy
  ) {}
  ...
  
  async rabbitTest(@Query() query: string) {
    await this.rmqClient.emit("event-pattern", "123");
    return "finished";
  }
  
 }

데코레이트에 따라 controller, service를 설정할수있다. 무엇이든 메소드를 통해 emit할수 있다.

 

 

4. receive que

//node.js
var amqp = require("amqplib/callback_api");

amqp.connect(
  "RMQ_URL",
  function (error0, connection) {
    if (error0) {
      throw error0;
    }
    connection.createChannel(async function (error1, channel) {
      if (error1) {
        throw error1;
      }

      var exchange = "/";
      var queue = "RMQ_QUE";
      var eventPattern = "event-pattern";

      channel.assertQueue(queue, {
        durable: false,
      });

      console.log(
        " [*] Waiting for messages in %s. To exit press CTRL+C",
        queue
      );
      await channel.bindQueue(queue, exchange, eventPattern);
      channel.consume(
        queue,
        function (msg) {
          console.log(" [x] Received %s", msg.content.toString());
        },
        {
          noAck: true,
        }
      );
    });
  }
);

메세지를 받는 리모트 서비스를 node.js로 구현한 코드이다. 받긴하지만 아래와 같은 에러가 발생한다.

There is no matching event handler defined in the remote service. Event pattern: event-pattern

 

event pattern설정을 안했다는데, 다른 문서들을 확인해보니 NestJS에서 emit시 pattern을 지정해줘서 발생한듯하다.

아래 방식으로 리모트 서비스를 구현하면 정상작동된다.

export class AppClass {
  constructor(
    private readonly appService: AppService,
    @Inject("RMQ_SERVICE") private rmqClient: ClientProxy
  ) {}

  @EventPattern("event-pattern")
  async handleBookCreatedEvent(data: Record<string, unknown>) {
    console.log(data);
  }
}

 

이상입니다.

 

 

 

*코드가 깨지면 아래 링크 참조해주세요.

https://medium.com/%EB%8F%84%EA%B9%A8%EB%B9%84-%EC%9D%B4%EC%95%BC%EA%B8%B0/nestjs-microservice-rabbitmq-%EC%A0%81%EC%9A%A9-%EC%A0%81%EC%9A%A9-76103aa6eaf9