[RabbitMQ] There is no matching event handler defined in the remote service.

YUSHIN KIM·2024년 11월 2일
0

TroubleShooting

목록 보기
2/3

개요: 문제 상황 이해

이 링크의 문제와 같은 현상을 겪었다.

기본적으로 제목과 같이 There is no matching event handler defined in the remote service.와 같은 문구가 에러로 뜨는 것 자체는 서버에 이벤트 핸들러가 등록되어 있지 않으니

@EventPattern('이벤트 이름')
  async handleData(data: any) {
    this.logger.debug('Received data:', data);
  }

이렇게 핸들러를 등록해 주어야 한다는 것이다.

마이크로서비스 A와 B가 있고 A에서 B로 메시지를 보내는 상황이라고 가정하자. 이 문제는 A에서 메시지 큐를 통해 이벤트를 emit하면 이상하게도 한 번은 무조건 B의 핸들러가 메시지를 받고, 한 번은 무조건 A에서 저 오류가 발생한다. 그러니까 홀수 번째엔 성공하고, 짝수 번째엔 실패하는 것이다(또는 그 반대).

RabbitMQ의 작동 원리

round-robin dispatching

출처: https://stackoverflow.com/questions/47017317/rabbitmq-and-python-3-how-to-consume-message-from-different-queues-with-priorit

문제는 RabbitMQ의 작동 원리와 관련이 있었다. Round-Robin Dispatching이라고도 하는 이 기법은 큐를 구독하고 있는 마이크로서비스들에게 부하를 분산하기 위해 설계된 방법으로, 이벤트를 emit했을 때 구독하고 있는 모든 마이크로서비스가 해당 알림을 받는 것이 아니라 순차적으로 알림을 받게 된다.

RabbitMQ의 작동 원리와 문제의 관련성

생각보다 간단했다. 앞서 가정했듯이 A에서 B로 이벤트를 emit하는 상황인데, A와 B의 main이 모두 다음과 같은 식으로 작성되어 있었다.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { rmqOption } from './config/rmq.option';

async function bootstrap() {
  // HTTP server
  const app = await NestFactory.create(AppModule);

  // RabbitMQ Microservice
  app.connectMicroservice(rmqOption);
  await app.startAllMicroservices();

  await app.listen(8079);
}
bootstrap();

그러니까 같은 rmqOption을 공유하고 있었던 것이다. 그래서 A와 B가 둘 다 같은 큐를 구독하게 되었는데 Round-Robin Dispatching이 되니 두 번 중 한 번은 무조건 A에게 이벤트가 emit되고, A에 해당 이벤트에 해당 핸들러가 없어서 오류가 발생한 것이었다.

A에서 B로 단방향으로 이벤트를 emit하는 상황이므로, 만약 B에서 A로 이벤트를 emit해야 한다면 또 다른 큐를 사용해야 할 것이다.

profile
안녕하세요

0개의 댓글