티스토리 뷰
728x90
반응형
지난 이야기
- 지난 이야기에서는 RabbitMQ를 사용하여 특정 클라이언트가 회원가입을 완료했을 경우 알림을 보냈습니다. 하지만 알림을 데이터 베이스에 저장하는 상황에서 예외가 발생하다면 어떻게 대처할 것인가에 대해서는 설명하지 않았습니다. 이번 편에서는 어떻게 대처할 수 있을까에대해 알아보겠습니다. 필자가 설명하는 방법에 대해 잘못된 방법이 있을 수 있으니 댓글을 남겨주시면 감사하겠습니다.
RabbitMQ Dead Letter Exchange
- 구글링을 통해 예외를 어떻게 처리할 수 있을까에 대해 살펴보던 중 Dead Letter에 대해 알게되었는데 이것을 사용하면 효과적으로 처리할 수 있지 않을까 싶어서 적용을 하게 되었습니다.
- Dead Letter Queue를 사용하는 이유는 Consumer에서 예외가 발생하면 기본적으로 예외가 발생한 메시지를 Queue에 다시 넣고 성공할 때까지 무한히 재시도하게 됩니다. 이때 무한히 재시도 하는것을 방지하기 위해 DLX(Dead-Letter-Exchange)로 보내는 것입니다.
RabbitMQ 설정 수정
💡 yml 파일 수정
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
listener:
simple:
retry:
enabled: true
initial-interval: 3s # 최초 재시도 간격 시간
max-interval: 10s # 재시도 간격 시간
max-attempts: 2 # 재시도 최대 횟수
multiplier: 2 # 재시도 간격 시간을 점진적으로 높입니다.
# initial-interval * multiplier 계산되며 max-interval 값보다 높으면 max-interval 값을 사용합니다.
💡 RabbitMQ Config 수정
- reject된 메시지를 Dead Letter Queue로 전송할 수 있도록 기존 Queue를 수정해줍니다.
- Dead Letter에 대한 Queue, Exchange, Binding을 설정해줍니다.
@EnableRabbit
@Configuration
public class RabbitMQConfig {
@Bean
Queue queue() {
return QueueBuilder.durable("server-queue")
.deadLetterExchange("deadLetterExchange")
.build();
}
@Bean
public Queue deadLetterQueue() {
return QueueBuilder.durable("dead-letter-queue").build();
}
@Bean
FanoutExchange exchange() {
return new FanoutExchange("fanoutExchange");
}
@Bean
FanoutExchange deadLetterExchange() {
return new FanoutExchange("deadLetterExchange");
}
@Bean
Binding binding() {
return BindingBuilder
.bind(queue())
.to(exchange());
}
@Bean
Binding deadLetterQueueBinding() {
return BindingBuilder
.bind(deadLetterQueue())
.to(deadLetterExchange());
}
@Bean("rabbitTemplate")
RabbitTemplate rabbitTemplate(@Qualifier("RabbitConnectionFactory") ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter());
return rabbitTemplate;
}
@Primary
@Bean("RabbitConnectionFactory")
@ConfigurationProperties("spring.rabbitmq")
public CachingConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
return connectionFactory;
}
@Bean
MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
}
💡 RabbitMQ Consumer 수정
- @RabbitListener 어노테이션을 사용하여 Dead Letter Queue를 경청할 수 있도록 설정해줍니다.
- ackMode를 사용하여 메시지가 유실되지 않도록 처리합니다.
@Component
@RequiredArgsConstructor
public class RabbitMQConsumer {
private final RabbitTemplate rabbitTemplate;
private static final String EXCHANGE_NAME = "amq.topic";
private final ObjectMapper objectMapper;
private final NotificationService notificationService;
@RabbitListener(queues = "server-queue")
public void consume(NotificationMessage notification) {
NotificationResponse response = notification.notificationSend(notificationService);
sendMessage(response);
}
@RabbitListener(queues = "dead-letter-queue", ackMode = "MANUAL")
public void deadLetterConsume(NotificationMessage notification) {
NotificationResponse response = notification.notificationSend(notificationService);
sendMessage(response);
}
private void sendMessage(NotificationResponse response) {
try {
String json = objectMapper.writeValueAsString(response);
rabbitTemplate.convertAndSend(EXCHANGE_NAME, response.getRoutingKey(), json);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
전체적인 예제 소스는 깃허브에서 확인할 수 있습니다. https://github.com/kdg0209/rabbitmqExample
728x90
반응형
'JAVA > SpringBoot' 카테고리의 다른 글
Spring Boot Excel Download 2편 (0) | 2023.05.02 |
---|---|
Spring Boot Excel Download 1편 (0) | 2023.05.02 |
Spring Boot - RabbitMQ를 사용하여 알림 발송 1편 (0) | 2022.11.20 |
Spring Boot - Server Sent Event를 사용한 실시간 알림 (0) | 2022.10.28 |
Spring Boot - @Transactional 전파 옵션 및 예외 처리 (0) | 2022.06.27 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 자바 백엔드 개발자 추천 도서
- 트랜잭셔널 아웃박스 패턴 스프링 부트 예제
- spring boot 엑셀 다운로드
- microkernel architecture
- transactional outbox pattern spring boot
- spring boot excel download paging
- spring boot redisson 분산락 구현
- transactional outbox pattern
- 람다 표현식
- spring boot excel download oom
- 트랜잭셔널 아웃박스 패턴 스프링부트
- redis sorted set으로 대기열 구현
- 레이어드 아키텍처란
- spring boot redisson sorted set
- spring boot redisson destributed lock
- 공간 기반 아키텍처
- pipe and filter architecture
- redis sorted set
- redis 대기열 구현
- pipeline architecture
- space based architecture
- service based architecture
- JDK Dynamic Proxy와 CGLIB의 차이
- spring boot poi excel download
- 서비스 기반 아키텍처
- spring boot redis 대기열 구현
- polling publisher spring boot
- java userThread와 DaemonThread
- java ThreadLocal
- @ControllerAdvice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함