글 요약
- 목표: RabbitMQ 기반 비동기 메시지 큐 도입을 통해 대규모 트래픽에서 입찰 이벤트의 안정적 처리와 서버 부하 분산 경험
- 문제: 기존 동기 처리 방식에서 발생하는 DB 부하 집중, 응답 지연, 트랜잭션 지연에 따른 장애 위험
- 해결: 메시지 큐를 활용한 비동기 처리 구조로 전환, Ack/재시도/DLQ 적용으로 메시지 신뢰성 확보
- 배운 점: 비동기 아키텍처 도입으로 서버 응답 속도 30% 이상 개선, 장애 영향 최소화, 메시지 재처리 문제 해결 및 날짜 타입 직렬화 처리 경험
프로젝트 배경 및 목적
이번 Auction 서버 프로젝트에서는 기존 동기 처리 방식의 한계를 극복하고, RabbitMQ 기반 비동기 메시지 큐 시스템을 도입하는 것을 목표로 삼았습니다.
대규모 트래픽 상황에서 안정적인 입찰 이벤트 처리와 서버 부하 분산을 위해 실제 서비스에 메시지 큐 패턴을 적용하며, 백엔드 확장성과 안정성에 대해 직접 경험하고자 했습니다.

실습 환경 및 설정
- RabbitMQ 설치: Windows 환경, RabbitMQ 공식 다운로드
- 관리 콘솔 접속: http://localhost:15672/#/ (기본 ID/PW: guest/guest)
설치 후, 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 등) 직렬화 처리를 반드시 확인하세요.
- 예외 발생 시 메시지 재처리 정책을 명확히 설계해 무한 재처리를 방지해야 합니다.
- 큐, 익스체인지, 라우팅 키 설정은 꼭 맞춰야 메시지가 정상 전달됩니다.
참고
https://github.com/gamsayeon/Auction-Server
GitHub - gamsayeon/Auction-Server: 대용량 트래픽을 목표로한 중고 경매 서버
대용량 트래픽을 목표로한 중고 경매 서버. Contribute to gamsayeon/Auction-Server development by creating an account on GitHub.
github.com
'Toy Project > Auction-Server' 카테고리의 다른 글
| Auction 서버 프로젝트 JPA 적용하기 (1) | 2025.07.07 |
|---|---|
| Elasticsearch 도입 전 Auction-Server 성능 테스트 결과와 개선 방향 탐색 (0) | 2024.03.27 |
| Auction-Server에 Docker 적용하기: 개발과 배포의 효율적인 관리 (0) | 2024.03.11 |
| 경매 서버 성능 최적화: 경매 서버의 Elasticsearch 도입 (0) | 2024.01.08 |