RabbitMQ 이벤트 처리에서 발생한 LinkedHashMap 역직렬화 문제와 해결 과정
문제 상황
Spring Boot와 RabbitMQ를 활용한 이벤트 기반 아키텍처에서 사용자 탈퇴 이벤트를 처리하는 과정에서 예상치 못한 문제가 발생했습니다.

이벤트 발행은 정상적으로 이루어졌지만, 수신 측에서 데이터를 처리할 때 타입 캐스팅 오류가 발생했습니다. 3회 재시도 후 DLQ(Dead Letter Queue)로 메시지가 이동하면서 데이터 일관성 문제가 발생할 수 있는 상황이었습니다.
문제 원인 분석
Jackson 역직렬화 과정에서의 타입 손실
RabbitMQ에서 메시지를 수신할 때 Jackson 라이브러리가 JSON을 Java 객체로 역직렬화하는 과정에서 문제가 발생했습니다.
// 발행 시점의 구조
EventWrapper<UserWithdrawnData> eventWrapper = EventWrapper.of(
EventTypeNames.USER_WITHDRAWN,
new UserWithdrawnData(userId, email, nickname)
);
하지만 수신 측에서는 제네릭 타입 정보가 소거되어 다음과 같은 상황이 발생했습니다:
// 수신 시점의 실제 구조
EventWrapper<?> eventWrapper // data 필드가 LinkedHashMap으로 역직렬화됨
제네릭 타입 소거(Type Erasure)의 영향
Java의 제네릭 타입 소거로 인해 런타임에서는 EventWrapper<UserWithdrawnData>의 구체적인 타입 정보가 사라집니다. Jackson은 이런 경우 기본적으로 Map<String, Object> 형태인 LinkedHashMap으로 데이터를 역직렬화합니다.
// 기존 코드 - 실패하는 캐스팅
UserEventMessage.UserWithdrawnData data =
(UserEventMessage.UserWithdrawnData) eventWrapper.data(); // ClassCastException 발생
최종 해결책: ObjectMapper.convertValue() 활용
가장 깔끔하고 안전한 해결책은 ObjectMapper의 convertValue() 메서드를 활용하는 것이었습니다.
구현 코드

ObjectMapper.convertValue()의 장점
1. 타입 안전성 보장
convertValue() 메서드는 런타임에 타입 정보를 활용하여 안전한 변환을 수행합니다. LinkedHashMap에서 목표 객체 타입으로의 변환을 자동으로 처리합니다.
2. 예외 처리 일관성
변환 실패 시 명확한 예외를 발생시켜 문제를 쉽게 추적할 수 있습니다.
3. 코드 간결성
복잡한 Map 조작 코드나 수동 객체 생성 로직 없이 한 줄로 변환이 완료됩니다.
4. 기존 패턴과의 일관성
프로젝트 내 다른 컴포넌트들도 동일한 ObjectMapper를 사용하고 있어 일관된 접근 방식을 유지할 수 있습니다.
correlationId 추가 구현
문제 해결과 함께 분산 시스템에서의 이벤트 추적을 위해 correlationId도 구현했습니다.
발행 측 구현

수신 측 구현

결과 및 효과
문제 해결
- LinkedHashMap 타입 캐스팅 오류 완전 해결
- 3회 재시도 후 DLQ 이동 문제 해결
- 데이터 일관성 보장
운영 개선

추적성 향상
correlationId 도입으로 분산 시스템에서 전체 이벤트 플로우를 추적할 수 있게 되었습니다:
# 단일 명령어로 전체 플로우 추적
grep "user-withdrawn-123" /logs/*.log
교훈과 시사점
1. 제네릭과 직렬화의 복합적 문제
Java의 제네릭 타입 소거와 Jackson 라이브러리의 역직렬화 방식이 결합되어 발생한 문제였습니다. 이런 상황에서는 명시적인 타입 변환 로직이 필요합니다.
2. ObjectMapper의 다양한 활용
ObjectMapper.convertValue()는 단순한 JSON 파싱뿐만 아니라 런타임 타입 변환에서도 강력한 도구가 될 수 있습니다.
3. 분산 시스템에서의 추적성
이벤트 기반 아키텍처에서는 각 이벤트에 고유한 추적 ID를 부여하여 전체 플로우를 추적할 수 있도록 하는 것이 중요합니다.
4. 방어적 프로그래밍
메시지 수신 시점에서 충분한 검증과 예외 처리를 통해 시스템의 안정성을 확보할 수 있습니다.
이번 경험을 통해 분산 시스템에서의 데이터 직렬화/역직렬화 문제와 이벤트 추적의 중요성을 다시 한 번 깨달을 수 있었습니다. 특히 타입 안전성과 운영 편의성을 동시에 확보하는 것이 얼마나 중요한지 실감할 수 있었습니다.