티스토리 뷰

 

기존 재시도 방식의 문제점

 

외부 시스템과 연동하는 애플리케이션을 개발하다 보면, 요청 직후 즉시 재시도할 경우 오히려 실패 확률이 높아지는 상황을 경험하게 된다.
그래서 보통은 일정 시간 대기 후 재시도를 수행하는 방식을 사용한다.

 

내가 운영하던 시스템은 애플리케이션 코드에서 직접 delay를 두고, 이후 큐에 메시지를 재전송하는 방식으로 재시도를 처리하고 있었다.

처음에는 단순하고 직관적인 방식처럼 보였지만, 신규 외부 시스템이 추가로 연동되는 과정에서 문제점이 드러나기 시작했다.

 

  • 애플리케이션 재시작 시 대기 중이던 메시지가 유실됨
  • 인스턴스 장애 시 재시도 자체가 수행되지 않음

 

결과적으로 재시도를 위해 넣은 delay 코드가 오히려 메시지 유실과 안정성 저하의 원인이 되고 있었다.

 

이 문제를 개선하기 위해, 애플리케이션 내부에서 시간을 관리하는 방식 대신 메시지를 안전하게 보관하고 일정 시간 이후 다시 전달할 수 있는 구조가 필요하다고 판단했다. 그 과정에서 SQS Delay Queue라는 기능을 알게 되었다.

 

SQS를 사용하고 있다면, 이러한 문제를 Delay Queue를 통해 간단하게 해결할 수 있다.

 

 

SQS Delay Queue란?

SQS Delay Queue는 메시지를 큐에 넣자마자 바로 소비되지 않도록, 일정 시간 동안 보이지 않게 지연시키는 기능이다.

 

동작 방식

Delay Queue의 동작 흐름은 다음과 같다.

 

  1. Producer가 메시지를 큐에 전송한다.
  2. 설정된 Delay 시간 동안 메시지는 큐에 존재하지만 Consumer에게는 보이지 않는다.
  3. Delay 시간이 지나면 일반 메시지처럼 Consumer가 수신할 수 있는 상태가 된다.
  4. Consumer가 메시지를 수신하고, 처리한다.

 

Delay 설정 방법

Delay는 두 가지 방식으로 설정할 수 있다.

 

  • 큐 단위 설정 : 해당 큐에 들어오는 모든 메시지에 동일한 Delay 적용
  • 메시지 단위 설정 : 메시지를 전송할 때 개별적으로 Delay 지정

Delay는 기본 0초이며, 최대 15분까지 설정할 수 있다.

 

Delay Seconds와 Visibility Timeout의 차이

옵션을 살펴보면 Delay Seconds와 Visibility Timeout 모두 메시지를 ‘보이지 않게’ 만드는 설정처럼 보인다. 하지만 두 기능의 목적과 동작 시점은 다르다.

 

공식 문서에서는 다음과 같이 설명하고 있다.

Delay queues are similar to visibility timeouts because both features make messages unavailable to consumers for a specific period of time. The difference between the two is that, for delay queues, a message is hidden when it is first added to queue, whereas for visibility timeouts a message is hidden only after it is consumed from the queue. The following diagram illustrates the relationship between delay queues and visibility timeouts.



출처 : https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-delay-queues.html

 

 

  • Delay Seconds
    • 메시지를 큐에 처음 추가될 때부터 일정 시간 동안 보이지 않게 숨겨진다.
    • 모든 Consumer에게 메시지가 보이지 않는다.
  • Visibility Timeout
    • 메시지가 큐에서 소비된 이후 일정 시간 동안 보이지 않게 숨겨진다.
    • 다른 Consumer가 동일 메시지를 중복 처리하는 것을 방지하기 위한 장치다.

 

 

정리하면 Delay Seconds는 처음부터 아무도 못 보게 숨기는 것이고, VIsibility TImeout은 누군가 가져간 뒤 모두에게 숨기는 것으로 볼 수 있다.

 

 

SQS Delay Queue로 재시도 구조 개선

Delay Queue를 적용한 이후 재시도 흐름은 다음과 같이 변경되었다.

 

기존 구조

  1. 요청 실패
  2. 애플리케이션 내부에서 coroutine delay() 로 일정 시간 대기
    1. 애플리케이션 재시작 또는 인스턴스 장애 발생시 대기 중이던 메시지가 유실될 수 있음
  3. 대기 이후 큐에 메시지 재전송 후 Consumer가 메시지 수신하여 처리

 

개선 구조

  1. 요청 실패
  2. 재시도 메시지를 SQS에 즉시 전송하고, Delay Seconds 로 일정 시간 대기
    1. SQS가 메시지를 안전하게 보관
  3. 대기 이후 메시지가 Consumer에게 노출되고 Consumer가 메시지 수신하여 처리

 

 

참고자료

'Infra' 카테고리의 다른 글

GitHub Actions 시작하기 - 구성요소  (0) 2024.04.07
[AWS] CloudFront?  (0) 2022.06.21
[Network] 로드밸런서를 쓰는 이유, 기능 정리  (0) 2021.05.24
댓글