Development

SQS DLQ 적체를 1시간 안에 풀기 위한 소비자 복구 플레이북

Mike발행일 2026년 4월 3일읽는 시간 약 3

💡 Key Takeaways

  • DLQ 복구는 재처리 속도보다 재적체를 막는 순서 설계가 먼저다.
  • 가시성 타임아웃, 동시성, 재시도 백오프를 한 세트로 조정해야 처리량이 안정된다.
  • 복구 중에는 성공 건수보다 실패 유형 분포와 처리 지연 상단 구간을 함께 봐야 한다.

SQS DLQ 적체를 1시간 안에 풀기 위한 소비자 복구 플레이북

새벽 배치 장애가 난 다음 날 아침, 주문 후처리 큐가 정상으로 돌아왔는데도 고객 알림이 계속 늦게 가는 상황을 겪었습니다. 원인을 보니 본 큐가 아니라 DLQ에 쌓인 메시지가 4만 건을 넘겼고, 담당자가 급한 마음에 DLQ를 본 큐로 한 번에 되돌리면서 같은 예외가 반복돼 적체가 더 커졌습니다. 당시 가장 큰 실수는 “일단 다시 넣으면 처리되겠지”라는 낙관이었습니다. 실제 운영에서는 실패 원인이 아직 살아 있는 상태에서 대량 리드라이브를 걸면, API 제한과 DB 락 대기가 동시에 올라가고 소비자 스레드가 긴 타임아웃에 묶여 전체 처리율이 떨어집니다. 그래서 우리 팀은 복구 시작 전에 15분을 써서 실패 유형을 세 갈래로 나눕니다. 즉시 재처리 가능한 메시지, 외부 의존성 복구 후 처리해야 할 메시지, 데이터 보정이 필요한 메시지로 나누고, 각 그룹의 목표 처리 시간을 먼저 선언합니다. 이 선행 분류만 해도 복구 시간 예측 오차가 크게 줄어 실무 커뮤니케이션이 안정됩니다.

판단 기준은 복잡하게 늘리지 않고 네 가지 숫자로 고정했습니다. 첫째, 메시지 연령 상위 95퍼센타일을 봐서 사용자 체감 위험을 판단합니다. 둘째, 실패 코드 분포를 집계해 동일 예외가 60퍼센트 이상이면 코드 수정 없이 재처리를 금지합니다. 셋째, 가시성 타임아웃 대비 평균 처리시간 비율을 계산해 1을 넘는 소비자 그룹을 우선 조정합니다. 넷째, 리드라이브 분당 투입량을 현재 정상 처리량의 30~40퍼센트로 제한합니다. 이 기준이 필요한 이유는 DLQ 복구가 보통 “빨리 비우기”로 오해되기 때문입니다. 하지만 실제로는 본 큐 SLO를 지키면서 부채를 줄이는 작업입니다. 지난달에는 외부 결제 API 429가 원인이었는데, 투입량을 욕심내지 않고 백오프를 늘린 팀이 50분 만에 정상화했고, 반대로 전체 메시지를 한 번에 되돌린 팀은 2시간 넘게 재적체를 반복했습니다. 같은 인프라에서도 의사결정 기준이 결과를 갈랐습니다.

실행 절차는 준비, 제한 복구, 점진 확장, 종료 검증 네 단계로 운영합니다. 준비 단계에서 DLQ 메시지 샘플 200건을 뽑아 실패 원인을 태깅하고, 태그별로 재처리 가능 여부를 명시합니다. 제한 복구 단계에서는 컨슈머 동시성을 평소의 60퍼센트로 낮추고, 가시성 타임아웃을 처리시간 p95의 1.5배로 맞춥니다. 이때 리드라이브는 5분 간격 배치로 넣고 배치 사이에 실패율과 처리 지연을 확인합니다. 점진 확장 단계에서는 실패율이 3회 연속 기준선 이내일 때만 투입량을 10퍼센트씩 올립니다. 우리 팀은 여기서 한 번 크게 배웠습니다. 예전에는 CPU 여유만 보고 동시성을 먼저 키웠다가 DB 커넥션 풀이 바닥나며 오히려 메시지 만료가 늘었습니다. 지금은 동시성보다 외부 의존성의 한계치, 특히 쓰기 API의 초당 허용량을 먼저 고정하고 그 안에서만 확장합니다. 마지막 종료 검증에서는 DLQ 잔량 0보다 더 중요한 지표로, 최근 30분 신규 실패 메시지의 재유입률을 확인합니다.

운영 체크리스트는 복구 속도와 재발 방지를 같이 다루어야 효과가 있습니다. 복구 전에는 “리드라이브 중단 조건”을 반드시 문장으로 박아 두세요. 예를 들어 실패율 8퍼센트 초과 10분 지속, 외부 API 5xx 급증, DB 대기시간 두 배 초과 같은 조건입니다. 복구 중에는 한 명이 큐 조작만 하고 다른 한 명이 지표와 로그를 전담하면 판단 지연을 줄일 수 있습니다. 복구 후에는 DLQ를 비웠다는 사실로 끝내지 말고, 실패 상위 원인 3개에 대해 코드 수정·재시도 정책·알람 임계치 중 무엇을 바꿀지 같은 날 결정해야 합니다. 우리는 이 후속 결정을 미뤘다가 일주일 뒤 비슷한 적체를 다시 맞은 적이 있습니다. 결론적으로 DLQ 운영의 핵심은 “빨리 처리”가 아니라 “같은 실패를 다시 만들지 않는 복구 리듬”입니다. 이 리듬을 팀 규칙으로 고정하면, 급한 상황에서도 품질을 잃지 않고 1시간 내 정상권 복귀가 가능합니다.

함께 읽으면 좋은 글

Development

Kubernetes 노드 드레인 중 503 급증을 막는 무중단 운영 플레이북

2026-04-02
Development

Node.js OOMKilled 반복 장애를 40분 안에 멈추는 운영 플레이북

2026-03-28

본문 작성/검수 원칙은 편집 원칙에서 확인할 수 있습니다.

← 목록으로 돌아가기