pile·
백엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

실패한 메시지는 어디로 가야 할까?- Kafka Retry/DLT 설계와 운영에서 밟은 3가지 함정

여기어때 정산개발팀 백엔드 개발자가 Kafka 컨슈머의 실패 처리를 non-blocking 재시도와 공통 DLT(Dead Letter Topic)로 표준화한 공통 라이브러리 구현 과정을 공유한다. 정산 시스템의 각 Kafka 컨슈머가 제각각 다른 방식으로 실패를 처리하던 상황을 @CommonKafkaRetry 어노테이션 하나로 일관되게 표준화하고, 그 과정에서 Spring Kafka의 3가지 숨겨진 함정을 발굴해 해결한 실전 기록이다.

핵심 포인트
  • @CommonKafkaRetry 어노테이션 하나로 non-blocking 재시도 + 공통 DLT를 표준화하는 공통 라이브러리 설계 (Java 17, Spring Boot 3.5, Spring Kafka 3.3)
  • non-blocking 재시도: 실패 메시지를 retry topic으로 발행, 원래 파티션은 즉시 해제되어 다른 메시지 처리 계속
  • 함정 1: 역직렬화 실패 시 원본 메시지 바이트가 소실 → DLT에 보존해야 할 원본 데이터 없음, 역직렬화 오류 별도 포착 필요
  • 함정 2: 프레임워크 확장 포인트(재시도 스케줄러·직렬화기)의 숨겨진 내부 배선 → 직접 설정 시 예상치 못한 동작 발생
  • 함정 3: retry topic 처리 후 메시지 헤더의 original topic/partition/offset이 retry topic 메타데이터로 덮어씌워짐 → 원본 위치 추적 불가
  • DLT(Dead Letter Topic): 재시도 횟수 초과 메시지의 최종 도착지, 수동 처리·분석을 위해 보존
상세 정리
  • 배경: 정산 시스템 Kafka 컨슈머들이 각자 다른 방식으로 실패를 처리 → 일관성 부재, 운영 비용 증가
  • 목표: @CommonKafkaRetry 어노테이션 하나로 전체 실패 처리 표준화
  • 핵심 설계: blocking 재시도(파티션 블로킹) 대신 non-blocking 재시도(별도 retry topic 활용)
  • non-blocking 재시도 동작: 실패 메시지 → retry topic 발행 → 원래 파티션 즉시 해제 → 다른 메시지 처리 계속
  • @CommonKafkaRetry: retry 횟수·딜레이·DLT 설정을 선언적으로 지정하는 공통 어노테이션
  • 함정 1 원인·해결: 역직렬화 실패는 예외 발생 시점에 원본 바이트 소실 → 역직렬화 오류를 별도 포착해 원본 바이트를 명시적으로 보존하는 로직 추가
  • 함정 2 원인·해결: Spring Kafka 내부의 재시도 스케줄러와 직렬화기에 숨겨진 배선 존재 → 프레임워크 소스 분석 후 올바른 확장 포인트 사용
  • 함정 3 원인·해결: retry topic 처리 완료 후 Spring Kafka가 헤더의 original 좌표를 retry 메타데이터로 덮어씀 → 원본 topic/partition/offset을 별도 헤더에 미리 저장
  • 구현 스택: Java 17, Spring Boot 3.5, Spring Kafka 3.3
왜 읽나Spring Kafka에서 non-blocking 재시도와 DLT를 어노테이션으로 표준화하는 공통 라이브러리 구현기. 역직렬화 바이트 소실·프레임워크 확장 포인트 숨겨진 배선·retry 헤더 덮어쓰기라는 세 가지 실전 함정을 구체적 원인과 해결법과 함께 공개한다.
여기어때 (GC컴퍼니)
여기어때 (GC컴퍼니) 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 백엔드·twilio-engTwilio Engineering·

    Programmable Messaging에서 Verify API로 마이그레이션하기

    Twilio의 Programmable Messaging API로 자체 OTP 솔루션을 운영하던 서비스가 Verify API로 전환하는 방법을 코드 예시와 함께 설명한다. Verify는 OTP 전송·검증을 위한 전용 API로, 전화번호 구매, 토큰 생성, DB 저장·만료 관리를 내부에서 처리해 개발자가 직접 구현할 코드를 크게 줄인다.

    요약 이어보기
    #authentication#twilio#sms+2
  2. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 2부

    포스타입 백엔드 엔지니어가 벡터 기반 개인화 추천 시스템을 실제 운영하며 맞닥뜨린 성능 장애와 용량 문제를 해결한 과정을 담은 2부다. 수백만 개의 벡터 KNN 검색이 피크 시간대에 전체 Elasticsearch 검색 성능을 흔드는 문제부터 클러스터 OOM 사태까지, 쿼리 최적화와 인프라 분리 두 가지 경로로 근본 해결에 이른다.

    요약 이어보기
    #elasticsearch#vector-search#recommendation-system+2
  3. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 1부

    포스타입이 태그 기반 추천의 한계를 극복하고 벡터 임베딩 기반 개인화 추천 시스템을 구축한 과정을 담은 1부다. 유사한 콘텐츠가 다른 용어를 쓰거나 동일한 태그가 전혀 다른 톤의 콘텐츠를 가리키는 문제를 임베딩 벡터로 해결하고, OpenSearch의 HNSW ANN 검색으로 수백만 벡터를 실시간 검색하는 시스템을 구축해 구매율 15% 향상을 달성했다.

    요약 이어보기
    #opensearch#vector-search#recommendation-system+2