글 요약

  • 목표: RabbitMQ 기반 비동기 메시지 큐 도입을 통해 대규모 트래픽에서 입찰 이벤트의 안정적 처리와 서버 부하 분산 경험
  • 문제: 기존 동기 처리 방식에서 발생하는 DB 부하 집중, 응답 지연, 트랜잭션 지연에 따른 장애 위험
  • 해결: 메시지 큐를 활용한 비동기 처리 구조로 전환, Ack/재시도/DLQ 적용으로 메시지 신뢰성 확보
  • 배운 점: 비동기 아키텍처 도입으로 서버 응답 속도 30% 이상 개선, 장애 영향 최소화, 메시지 재처리 문제 해결 및 날짜 타입 직렬화 처리 경험

프로젝트 배경 및 목적

이번 Auction 서버 프로젝트에서는 기존 동기 처리 방식의 한계를 극복하고, RabbitMQ 기반 비동기 메시지 큐 시스템을 도입하는 것을 목표로 삼았습니다.
대규모 트래픽 상황에서 안정적인 입찰 이벤트 처리와 서버 부하 분산을 위해 실제 서비스에 메시지 큐 패턴을 적용하며, 백엔드 확장성과 안정성에 대해 직접 경험하고자 했습니다.

 


실습 환경 및 설정

설치 후, Spring Boot와 연동하여 실습을 진행했습니다.


RabbitMQ 도입 배경 및 문제 인식

Auction 서비스는 입찰, 낙찰자 선정, 결제 등 다양한 이벤트가 실시간으로 발생합니다.
기존 동기 처리 방식에서는 동시 접속자가 몰릴 때 DB 부하가 급증하며, 트랜잭션 지연으로 인한 응답 지연과 장애 확산 위험이 있었습니다.
이 문제를 해결하기 위해 서비스 모듈 간 결합도를 낮추고, 안정성과 확장성을 보장하는 비동기 아키텍처 구축이 필요했습니다.

구분 동기 처리 문제점 비동기 처리 (RabbitMQ 도입) 개선점
처리 방식 요청마다 DB에 즉시 접근하여 처리 요청을 메시지 큐에 쌓아 비동기 처리
트래픽 대응 동시 접속 시 DB 부하 급증 큐에 요청을 버퍼링해 서버 부하 분산 가능
장애 전파 트랜잭션 지연이 전체 서비스 응답 지연으로 연결 메시지 단위 비동기 처리로 장애 영향 최소화
서비스 확장성 서비스 간 결합도 높아 확장 어려움 Producer/Consumer 분리로 유연한 확장 가능

구현 내용 및 주요 경험

  • RabbitMQ 서버 구성 및 Spring Boot 연동
    메시지 발행자(Producer)와 수신자(Consumer)를 구현해 입찰 이벤트가 발생할 때 메시지를 큐에 발행하고, 별도의 Consumer가 비동기적으로 처리하도록 설계했습니다.
// Producer - 메시지 발행 예시
rabbitTemplate.convertAndSend("exchangeName", "routingKey", messageObject);

// Consumer - 메시지 수신 및 처리 예시
@RabbitListener(queues = "queueName")
public void handleMessage(MessageType message) {
    // 메시지 처리 로직
}
  • 메시지 신뢰성 확보
    Ack(확인 응답): 소비자가 메시지를 정상 처리했음을 확인하여 메시지 유실을 방지합니다.
    재시도 로직: 처리 실패 시 메시지를 재전송하여 메시지가 누락되지 않도록 합니다.
    Dead Letter 큐(DLQ): 재시도 후에도 실패한 메시지를 별도로 저장하여 문제 원인을 추적하고 수동 처리할 수 있게 합니다.

  • 예외 처리 및 무한 재처리 문제 해결
    입찰 가격 유효성 검사 중 예외 발생 시 메시지가 무한 재처리되는 문제가 있었는데, channel.basicReject(tag, false)를 통해 재처리를 막아 문제를 해결했습니다.
// custom 예외 발생 시 메시지 재처리 방지 예시
try {
    // 메시지 처리 로직
} catch (InputMismatchException e) {
    channel.basicReject(tag, false); // 메시지 거부 및 재전송 방지
}

 

  • LocalDateTime 직렬화/역직렬화 문제 대응
    JavaTimeModule 등록을 통해 LocalDateTime의 JSON 직렬화와 역직렬화를 정상 처리하도록 메시지 변환기를 구성했습니다.
// LocalDateTime 직렬화/역직렬화 문제 해결을 위한 ObjectMapper 설정
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());

프로젝트 성과 및 배운 점

대기 시간 관리 및 메시지 신뢰성 강화로 서비스 신뢰도를 높인 아키텍처 개선을 경험할 수 있었습니다.

이번 경험을 통해 메시지 큐 패턴의 중요성과 실제 운영 환경에서 발생하는 문제를 체험하며, 백엔드 시스템의 안정성 설계 역량을 키우는 값진 기회가 되었습니다.


추가 팁

  • 메시지 변환기 설정 시 Java 8 이상 날짜 타입(LocalDateTime 등) 직렬화 처리를 반드시 확인하세요.
  • 예외 발생 시 메시지 재처리 정책을 명확히 설계해 무한 재처리를 방지해야 합니다.
  • 큐, 익스체인지, 라우팅 키 설정은 꼭 맞춰야 메시지가 정상 전달됩니다.

 

+ Recent posts