생각 정리 - 실패한 메시지 재처리

Marble·2025년 3월 14일

생각 정리

목록 보기
3/4

진행중인 프로젝트에서 일정을 추가하고 일정에 대한 정보를 API 요청을 통해 서버에 저장하려고 해요. 그런데 일정을 추가했을 때 네트워크 연결 상태 등 에러가 발생할 수 있잖아요?

이때 어떻게 할 지 고민을 하다가 UX 관점에서는 유저가 일정을 추가했는데 프로그레스바를 보여주면서 다른 작업을 못하게 막는 것은 안 좋다 생각했어요. 그래서 앱에서는 일정이 추가된 것처럼 보이고 나중에 네트워크 연결 등의 문제가 해결됐을 때 API를 요청하게끔 짜면 되겠다 생각을 했죠.

프로젝트를 같이 진행중인 지인에게 이에 대해 말했을 때 DLQ(Dead Letter Queue)를 구현해보면 되겠다 해서 이번에는 DLQ에 대해 알아보려고 해요

DLQ(Dead Letter Queue)

DLQ는 처리되지 못한 메시지를 보관하는 큐로 메시지 큐 시스템에서 실패한 메시지나 반복적인 오류가 발생한 메시지를 따로 저장해서 재처리할 수 있도록 도와주는 역할을 합니다. 지금 저의 상황에 필요한 기능이에요

DLQ는 위에서도 말했듯이 메시지가 정상적으로 보내지지 않았을 때 필요한데 예시 상황으로는 다음과 같아요

  • 메시지 처리 실패
    예를 들어, 서버에서 메시지를 처리하는 도중 예외(Exception)가 발생하면? 메시지를 정상적으로 처리할 수 없죠
  • 메시지 만료(TTL Expiration):
    메시지가 일정 시간 동안 처리되지 않으면 만료(Time-To-Live, TTL)됩니다
  • 최대 재시도 횟수 초과(Retry Limit Exceeded):
    일반적으로 메시지가 처리 실패하면 재시도를 하지만 지정된 횟수를 넘어가는 경우 무한 루프 방지를 위해 DLQ로 보냅니다
  • 잘못된 형식의 메시지(Invalid Message Format):
    예상과 다른 데이터 형식이 들어와서 처리할 수 없는 경우도 해당됩니다

DLQ의 구조는 다음과 같이 메인 큐에서 작업하다 실패한 메시지를 저장하는 단순한 구조에요

[Producer] → [Main Queue] → [Consumer]
                  ↓ (처리 실패)
         [Dead Letter Queue (DLQ)]

장점

DLQ를 사용했을 때 장점은 다음과 같아요

  • 메시지 손실 방지
    실패한 메시지를 버리지 않고 DLQ에 저장하여 추후 재처리 가능합니다
    데이터를 잃지 않도록 보호할 수도 있죠
  • 문제 분석 및 디버깅 용이
    DLQ에 쌓인 메시지를 분석하여 왜 실패했는지 로그 확인이 가능합니다. 이를 버그 수정 및 성능 개선에 활용할수도 있죠
  • 서비스 안정성 향상
    실패한 메시지를 격리함으로써 실패한 메시지가 일반 큐를 계속 차지하며 큐가 가득 차는 문제 방지할 수있습니다
  • 유연한 재처리 전략 가능
    실패 메시지를 수동, 자동으로 확인하고 재처리할 수 있습니다

단점

장점이 있으면 단점이 있겠죠? 단점은 다음과 같아요

  • DLQ에 쌓인 메시지를 별도로 관리해야 함
    DLQ는 저장 공간이지 구현체가 아니에요. 그래서 DLQ가 자동으로 문제를 해결해 주지는 않죠. 이를 위해 실패 메시지를 재처리하는 로직을 구현해줘야 합니다
  • DLQ가 가득 차면 또 다른 병목이 될 수 있음
    DLQ 자체도 무한정 메시지를 보관할 수 없어요. DLQ의 크기를 설정하지 않거나 처리를 제대로 안 하면 DLQ도 오버플로우가 발생할 수 있습니다
  • 실패한 메시지를 복구하는 방법이 필요함
    단순히 DLQ에 저장하는 것이라면 구현을 안하는게 낫을 거에요. 저장된 메시지 중에서 어떤 메시지를 재처리할지, 어떤 것을 폐기할지 판단하는 로직이 필요하죠
  • 메시지 처리 지연 가능성
    만약 DLQ에서 수동으로 메시지를 처리한다면, 즉각적인 재처리가 어려워서 지연될 가능성이 있습니다

2,4번을 제외한 1,3번의 경우 개발자가 번거로운거 뿐이지 성능에 영향을 끼치진 않는 거 같아요

위에서도 언급했듯이 DLQ는 실패한 메시지를 저장하는 공간이기 때문에 정해진 구현 방법은 없어요.

현재 저의 프로젝트는 Core Data를 사용하기로 해서 Core Data에 실패한 메시지를 저장할 것 같아요. 특히 네트워크 연결 상태로 인해 실패한 메시지만 저장할건데 나중에 네트워크가 연결 되면 Core Data에 저장된 실패 메시지들을 API 요청을 하는 식으로 구현하고, 성공하면 Core Data에서 실패 메시지를 제거해서 불필요한 데이터를 제거할 거에요.

이러려면 네트워크 상태를 확인해주는 기능이 있어야겠죠? 그래서 다음에는 네트워크를 감지해주는 NWPathMonitor에 대해 공부해보려고 해요

profile
개발자가 되고 싶은 공돌이

0개의 댓글