Lambda SQS process failure
Lambda SQS 실패 처리는 왜 해야 하는가
Labmda와 SQS를 함께 사용할 때 메세지 실패 처리는 항상 발생한다. 문제는 실패 처리를 하지 않으면 오류를 탐지하기가 어려우며 메세지를 복구할 수 없는 상태로 방치하는 것이다. 매번 Cloudwatch 콘솔에 들어와 로그를 확인할 수 없으니 적절한 알람 설정과 재시도 파이프라인을 구성, 거기에 더불어 운영 대응 대책까지 세워놓는 것이 견고한 실패 처리 파이프라인이다. 이 글에서 Lambda+SQS 환경에서 실패 처리를 다룰 때 알아야 할 개념과 실무에서 어떤 기준으로 알람을 설정하고, 복구 흐름은 어떻게 설계해야 하는지를 정리한다.
실패 처리할 때 답해야 할 5가지 질문
실패 처리를 설계할 때는 아래 질문에 답해보면 좋다.
- 이 실패는 버려도 되는가?
- 다시 시도하면 성공할 가능성이 있는가?
- 중복 실행되면 문제가 생기는가?
- 얼마나 늦게 처리되어도 괜찮은가?
- 실패 메시지를 누가, 어떻게 복구할 것인가?
위 질문에 제대로 답할 수 있느냐가 에러 처리를 제대로 하는지를 판가름한다. 실패하면 버려도 되는가 - 이런 질문의 답은 기술 자체보다 도메인에 있다. 예를 들어 결제나 주문 관련 이벤트는 버려서는 안되지만 조회 로그 집계 이벤트는 일부 유실되어도 서비스에 치명적이지 않다. 즉, 실패 처리 정책은 단순 인프라 결정이 아니라 서비스 흐름과 데이터 중요도를 이해한 상태에서 결정해야 한다.
재시도 구조 설계
재시도 처리를 위해 알아야 할 개념들을 정리해보면 아래의 10가지 정도가 있다.
- retry
- visibility timeout
- maxReceiveCount
- DLQ
- redrive
- partial batch response
- idempotency
- CloudWatch metrics
- alarm threshold
- runbook
이를 작업 목적에 따라 정리하면,
| 목적 | 개념 | 내용 |
|---|---|---|
| 실패 감지 | CloudWatch metrics, alarm threshold | 실패가 발생했는지 어떻게 알 것인가 |
| 재시도 제어 | retry, visibility timeout, maxReceiveCount | 실패한 메시지를 언제, 몇 번 다시 처리할 것인가 |
| 실패 격리 | DLQ, partial batch response | 계속 실패하는 메시지를 어떻게 분리할 것인가 |
| 안전한 재처리 | idempotency, redrive | 중복 실행과 재처리를 어떻게 안전하게 할 것인가 |
| 운영 대응 | runbook | 알람을 받은 사람이 무엇을 할 것인가 |
이 중 몇 가지만 자세히 알아보자.
maxReceiveCount
maxReceiveCount는 SQS가 메세지를 수신받을 최대 횟수다. 메세지 처리에 실패하면 maxReceiveCount에 설정한 만큼 동일한 메세지를 큐에 다시 넣어 재처리를 돌릴 수 있다. 그 count를 넘어선 횟수만큼 처리에 실패한다면 설정해둔 DLQ로 메세지가 넘어간다.
partial batch response
partial batch response도 SQS와 lambda를 함께 사용할 때 사용하는 기능이다. lambda는 SQS 리스너로 사용될 때 batch size를 설정할 수 있는데 이를 10으로 했을 때, 메세지 10개 수신 중 9개를 성공하고 1개만 실패해도 partial batch response를 활성화하지 않았다면 전체 10개 메세지를 재처리하게 된다.
alarm
알람을 설정하는 기준은 알람을 받은 운영자가 이 에러를 직접 봐야하는가? 를 기준으로 설정해야 한다. 에러가 날 때마다 모든 에러에 알람을 걸어놓으면 일시적 외부 API 오류나 재시도 가능한 에러까지 알람이 발생해 결국 운영자가 알람을 자세히 보지 않게 되고 진짜 중요한 문제가 발생했을 떄 이를 간괗해버리는 문제로 이어질 수 있다.
- 재시도 할 수 없는 실패인지
- 사람이 직접 봐야하는 실패인지
를 파악해 알람을 구성해야 한다.
DLQ
DLQ를 단순히 실패 메세지 보관소가 아니라 메세지 보관 시간을 필터링해 알람을 설정하고 재시도를 한다거나 개발자가 직접 메세지를 보고 실패 원인을 파악해 메세지 파싱 오류인지, 외부 API 오류인지, 권한 오류인지 구분해 후처리까지 이어져야 제대로된 에러 처리 파이프라인을 구축했다고 할 수 있겠다.