TroubleShooting
25.03.17 RabbitMQ message 직렬화 문제 해결
ddong-kka
2025. 3. 17. 15:36
개요
order 와 product 간의 메시지를 주고 받는 과정에서 ListenerExecutionFailedException: Listener method could not be invoked with the incoming message
에러가 발생해 해결한 과정을 정리해본다.
Message
package com.devsquad10.product.application.dto.message;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@ToString
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StockDecrementMessage {
private UUID orderId;
private UUID productId;
private Integer quantity;
private String errorType;
}
두 서비스간에 동일한 message dto를 가지고 이벤트를 처리한다
그러나 전달은 되지만 직렬화 문제가 발생하고있다.
문제 발생 원인
- order 서비스에서 StockDecrementMessage를 전송했지만, product 서비스에서 이를 정상적으로 역직렬화하지 못해 ListenerExecutionFailedException 발생.
- RabbitMQ는 기본적으로 메시지를 바이트 배열(byte[])로 전달하지만 현재 내가 보는 StockDecrementMessage
메시지는 JSON 직렬화 방식을 사용해야한다. - UUID 타입을 포함하는 DTO를 JSON으로 주고받기 위해 Jackson2JsonMessageConverter 설정이 필요하다.
해결
@Configuration
public class OrderApplicationQueueConfig {
@Value("${message.exchange}")
private String exchange;
@Value("${message.queue.product}")
private String queueProduct;
@Bean
public TopicExchange exchange() {
return new TopicExchange(exchange);
}
@Bean
public Queue queueProduct() {
return new Queue(queueProduct);
}
@Bean
public Binding bindingProduct() {
return BindingBuilder.bind(queueProduct()).to(exchange()).with(queueProduct);
}
@Bean
public Jackson2JsonMessageConverter producerJackson2MessageConverter() {
return new Jackson2JsonMessageConverter();
}
}
@Configuration
public class ProductApplicationQueueConfig {
@Bean
public Jackson2JsonMessageConverter producerJackson2MessageConverter() {
return new Jackson2JsonMessageConverter();
}
}
메시지를 주고 받은 양쪽 서비스의 rabbitmq 설정에 Jackson2JsonMessageConverter 를 빈으로 등록해줬다.
이제 결과를 확인해본다.
결과 확인
@Slf4j
@RequiredArgsConstructor
@Component
public class ProductEndPoint {
private final ProductService productService;
@RabbitListener(queues = "${message.queue.product}")
public void handleStockDecrementRequest(StockDecrementMessage stockDecrementMessage) {
System.out.println("-------------------" + stockDecrementMessage.getQuantity());
}
}
1235 를 message 객체 안의 quantity 값으로 전달 해보았다.
정상적으로 전달되어 성공했다!