-
[RabbitMQ] 한 Queue에서 여러 타입의 Message 처리✉️ MQ 2023. 1. 5. 19:46
❗ 한 개의 Queue에 두 개 이상의 다른 타입 Message가 들어올 때의 처리!
한 개의 Exchange에 한 개의 Queue가 바인딩 된 상태
- exchange 타입 - topic
메시지 타입
두 개의 다른 클래스
SampleMessage
@Slf4j @Getter @AllArgsConstructor @NoArgsConstructor public class SampleMessage { private String name; private String content; }
OtherMessage
@Slf4j @Getter @AllArgsConstructor @NoArgsConstructor public class OtherMessage { private String name; private String content; private String writer; }
각 메시지 타입에 따라 다른 로직을 수행하도록 한다.
📤 Producer(Sender)
한 개의 큐로 서로 다른 타입의 객체를 보낸다.
@Slf4j @Service public class RabbitProducerService { @Autowired private RabbitTemplate rabbitTemplate; @Autowired private Queue queue; public void sendConvertSampleMessage(SampleMessage message) { rabbitTemplate.convertAndSend(queue.getName(), message); log.info("RabbitProducerService send SampleMessage {}", message.getContent()); } public void sendConvertOtherMessage(OtherMessage message) { rabbitTemplate.convertAndSend(queue.getName(), message); log.info("RabbitProducerService send OtherMessage {}", message.getContent()); } }
message 보내기
@Component public class TestRunner implements CommandLineRunner { @Autowired private RabbitProducerService producer; @Override public void run(String... args) throws Exception { SampleMessage testSampleMessage = new SampleMessage("beomsicA", "contentA"); producer.sendConvertSampleMessage(testSampleMessage); OtherMessage testOtherMessage = new OtherMessage("beomsicB", "contentB", "범석"); producer.sendConvertOtherMessage(testOtherMessage); } }
log 확인
RabbitMQ Web Management 페이지
→ 정상적으로 동작!!
📩 Consumer
이전과 달리 클래스 레벨에 @RabbitListener 를 지정한다.
@Slf4j @Component @RabbitListener(containerFactory = "SampleListenerContainerFactory", queues="test-queue") public class Receiver { @RabbitHandler public void listenerSampleMessage(SampleMessage message) { log.info("SampleMessage Received!! - {}", message.getContent()); } @RabbitHandler public void listenerOtherMessage(OtherMessage message) { log.info("OtherMessage Received!! - {}", message.getContent()); } }
@RabbitHandler 를 통해 메시지의 타입마다 다르게 매핑하도록 설정!!
결과
→ 메시지 타입마다 다른 메서드를 호출한다❗
📌 isDefault
위에서 사용한 메시지 타입인 SampleMessage 와 OtherMessage 외에 다른 타입이 전달될 수 있다.
- 해당 두 타입외에 대한 처리를 일괄적으로 할 수 있다.
다른 타입 추가
AMessage
@Getter @AllArgsConstructor @NoArgsConstructor public class AMessage { private Long id; private String name; }
BMessage
@Getter @AllArgsConstructor @NoArgsConstructor public class BMessage { private Long id; private String name; private String writer; }
Producer
4개 타입의 메시지를 send
@Slf4j @Service public class RabbitProducerService { @Autowired private RabbitTemplate rabbitTemplate; @Autowired private Queue queue; public void sendConvertSampleMessage(SampleMessage message) { rabbitTemplate.convertAndSend(queue.getName(), message); log.info("RabbitProducerService send SampleMessage {}", message.getContent()); } public void sendConvertOtherMessage(OtherMessage message) { rabbitTemplate.convertAndSend(queue.getName(), message); log.info("RabbitProducerService send OtherMessage {}", message.getContent()); } public void sendConvertMessageA(AMessage message) { rabbitTemplate.convertAndSend(queue.getName(), message); log.info("RabbitProducerService send SampleMessage {}", message.getContent()); } public void sendConvertMessageB(BMessage message) { rabbitTemplate.convertAndSend(queue.getName(), message); log.info("RabbitProducerService send OtherMessage {}", message.getContent()); } }
@Component public class TestRunner implements CommandLineRunner { @Autowired private RabbitProducerService producer; @Override public void run(String... args) throws Exception { SampleMessage testSampleMessage = new SampleMessage("beomsicA", "contentA"); producer.sendConvertSampleMessage(testSampleMessage); OtherMessage testOtherMessage = new OtherMessage("beomsicB", "contentB", "범석"); producer.sendConvertOtherMessage(testOtherMessage); AMessage testAMessage = new AMessage(1L, "contentAA"); producer.sendConvertMessageA(testAMessage); BMessage testBMessage = new BMessage(2L, "contentBB", "범석"); producer.sendConvertMessageB(testBMessage); } }
Consumer
Consumer 측에서 메시지를 처리할 때 @RabbitHandler의 isDefault 속성을 사용하면 @RabbitHandler에 의해 매핑되지 않은 타입에 대한 처리를 지원한다.
@Slf4j @Component @RabbitListener(containerFactory = "SampleListenerContainerFactory", queues="test-queue") public class Receiver { @RabbitHandler public void listenerSampleMessage(SampleMessage message) { log.info("SampleMessage Received!! - {}", message.getContent()); } @RabbitHandler public void listenerOtherMessage(OtherMessage message) { log.info("OtherMessage Received!! - {}", message.getContent()); } @RabbitHandler(isDefault = true) public void listenerDefault(Object obj) { log.info("Default Message Received!! - {}", obj); } }
결과
참고자료
https://docs.spring.io/spring-amqp/api/org/springframework/amqp/rabbit/annotation/RabbitHandler.html
https://velog.io/@dhk22/RabbitMQ-한-개-Queue에-여러-타입-Message-처리하기-RabbitHandler
'✉️ MQ' 카테고리의 다른 글
RabbitMQ + Spring Boot(2) (0) 2023.01.05 Rabbit MQ + Spring Boot(1) (1) 2023.01.04 Rabbit MQ (0) 2023.01.04 Message Queue 란❓ (0) 2023.01.04