JSCODE Logo
프로그래밍 과외블로그후기멘토진
회사명 : JSCODE대표 : 박재성사업자 등록번호 : 244-22-01557통신판매업 : 제 2023-인천미추홀-0381 호
학원 명칭 : 제이에스코드(JSCODE)원격학원학원설립ㆍ운영 등록번호 : 제6063호

서울특별시 구로구 경인로 20가길 11(오류동, 아델리아)

Copyright ⓒ 2025 JSCODE - 최상위 현업 개발자들의 프로그래밍 교육 All rights reserved.

이용약관개인정보처리방침
← 블로그 목록으로 돌아가기

[실습] Spring Boot로 Kafka에서 처리에 실패한 메시지를 재시도(Retry)하도록 만들기

JSCODE 박재성
JSCODE 박재성
2025-12-06
author
JSCODE 박재성
category
Kafka
createdAt
Dec 6, 2025
series
실전에서 바로 써먹는 Kafka 입문
slug
practice-retry-failed-messages
type
post
updatedAt
Dec 6, 2025 05:39 AM
👨🏻‍🏫
이전 강의에서는 Kafka를 통해 비동기적으로 이메일 발송 요청을 처리함으로써 사용자에게 빠르게 응답할 수 있다는 장점을 살펴봤다. 그러나 Consumer가 실제 작업에 실패했을 때 사용자에게 실패 여부를 전달할 수 없다는 단점이 있었다. 이번 시간에는 그 단점을 재시도(Retry) 방식을 활용해 해결해보자.
 

✅ Kafka에서 처리에 실패한 메시지를 재시도(Retry)하도록 만들기

  1. 의도적으로 실패하는 상황을 만들기 위해 Consumer 코드 수정하기
    1. EmailSendConsumer
      @Service public class EmailSendConsumer { @KafkaListener( topics = "email.send", groupId = "email-send-group" ) public void consume(String message) { System.out.println("Kafka로부터 받아온 메시지: " + message); EmailSendMessage emailSendMessage = EmailSendMessage.fromJson(message); // 잘못된 이메일 주소일 경우 실패 가정 if (emailSendMessage.getTo().equals("fail@naver.com")) { System.out.println("잘못된 이메일 주소로 인해 발송 실패"); throw new RuntimeException("잘못된 이메일 주소로 인해 발송 실패"); } // ... 실제 이메일 발송 로직은 생략 ... try { Thread.sleep(10000); // 이메일 발송을 하는 데 10초가 걸린다고 가정 } catch (InterruptedException e) { throw new RuntimeException("이메일 발송 실패"); } System.out.println("이메일 발송 완료"); } }
      위와 같이 코드를 작성한 뒤에 서버를 재실행시켜주자.
       
  1. Postman으로 실패 조건에 해당하는 API 요청 보내기
    1. Request Body
      { "from": "sender@naver.com", "to": "fail@naver.com", "subject": "제목", "body": "내용" }
      notion image
       
  1. Consumer 서버에 찍힌 로그 확인하기
    1. notion image
      요청을 보냈더니 Consumer 서버에서 아래와 같이 로그가 찍혔다. 재시도(Retry)에 대해서 아무런 코드를 작성하지 않았는데도 여러 번 재시도를 한 흔적이 로그로 남았다. 그리고 에러 메시지 바로 직전의 로그를 살펴보면 이렇게 작성되어 있다.
      Backoff FixedBackOff{interval=0, currentAttempts=10, maxAttempts=9} …
      이 메시지의 의미를 해석하자면 다음과 같다.
      • interval : 재시도를 하는 시간 간격 (ms)
        • interval=0일 경우 실패하자마자 즉시 재시도 한다는 뜻이다.
      • maxAttempts : 최대 재시도 횟수
        • maxAttempts=9인걸로 봐서 재시도를 9번까지 했다는 뜻이다.
      • currentAttempts : 지금까지 시도한 횟수 (최초 시도 횟수 + 재시도 횟수)
        • currentAttmpes=10인 이유는 최초 시도를 1번 하고 재시도를 9번 했기 때문이다.
       
👨🏻‍🏫
별도의 설정을 하지 않았는데 이미 기본값으로 재시도(retry) 전략이 설정되어 있다. 이 설정을 변경해서 적용시켜보자.
 
 

✅ 재시도(Retry) 정책 변경하기

  1. Consumer 코드 수정하기
    1. EmailSendConsumer
      @Service public class EmailSendConsumer { @KafkaListener( topics = "email.send", groupId = "email-send-group" // 컨슈머 그룹 이름 ) @RetryableTopic( // 총 시도 횟수 (최초 시도 1회 + 재시도 4회) attempts = "5", // 재시도 간격 (1000ms -> 2000ms -> 4000ms -> 8000ms 순으로 재시도 시간이 증가한다.) backoff = @Backoff(delay = 1000, multiplier = 2) ) public void consume(String message) { System.out.println("Kafka로부터 받아온 메시지: " + message); EmailSendMessage emailSendMessage = EmailSendMessage.fromJson(message); // 잘못된 이메일 주소일 경우 실패 가정 if (emailSendMessage.getTo().equals("fail@naver.com")) { System.out.println("잘못된 이메일 주소로 인해 발송 실패"); throw new RuntimeException("잘못된 이메일 주소로 인해 발송 실패"); } // ... 실제 이메일 발송 로직은 생략 ... try { Thread.sleep(10000); // 이메일 발송을 하는 데 10초가 걸린다고 가정 } catch (InterruptedException e) { throw new RuntimeException("이메일 발송 실패"); } System.out.println("이메일 발송 완료"); } }
      • 현업에서 보통 재시도 횟수는 3~5회 사이로 정하는 편이다. 왜냐하면 재시도를 너무 많이 할 경우 시스템 부하가 커질 수 있고, 너무 적으면 일시적인 장애에 대응하기 어렵기 때문이다.
      • 첫 재시도 간격은 짧게 설정하는 편이고, 그 이후 재시도 간격은 지수적(exponential)으로 증가하도록 설정하는 편이다. 그래야 일시적인 장애에 대해서는 첫 빠른 재시도로 대응이 가능하고, 장애가 조금 길어지는 경우라도 무의미하게 재시도하는 걸 방지하기 위함이다.
       
  1. 테스트해보기
    1. Spring Boot 서버를 재실행시키고 API 요청을 보내보자.
      notion image
      메시지 처리를 위해 정확히 5번까지 시도하고 에러를 발생시켰다. 그리고 각 시도를 할 때 1, 2, 4, 8초 간격으로 요청을 처리하는 걸 로그로 확인할 수 있다.
       
 
👨🏻‍🏫
재시도(retry)를 통해 실패한 요청을 다시 처리해서 성공적으로 처리 할수 있게끔 구성했다. 하지만 재시도(retry)를 여러번 했음에도 불구하고 작업이 실패하면 어떻게 해야 할까?
분명 사용자는 응답으로 성공을 받았기 때문에 ‘이메일 발송’이라는 작업이 정상적으로 처리될 거라고 예상하고 있을 것이다. 이런 상황에서는 추가로 어떻게 대처해야 하는 지 다음 강의에서 알아보자.
 
author
JSCODE 박재성
category
Kafka
createdAt
Dec 6, 2025
series
실전에서 바로 써먹는 Kafka 입문
slug
type
series-footer
updatedAt
Dec 6, 2025 05:39 AM
📎
이 글은 실전에서 바로 써먹는 Elasticsearch 입문 (검색 최적화편) 강의의 수업 자료 중 일부입니다.