Search

Amazon SQS 도입기

생성일
2022/03/07 01:42
태그
AWS
SQS
작성자

들어가며

1. Amazon SQS란?

Amazaon SQS의 SQS는 Simple Queue Service의 약자로, 마이크로 서비스, 분산 시스템 및 서버리스 애플리케이션을 쉽게 분리하고 확장할 수 있도록 지원하는 완전관리형 메시지 대기열 서비스입니다.
생산자(producer)인 Component 1에서 메시지를 Queue로 보내면 소비자(consumer)인 Component 2에서 메시지를 받아 처리한 후, 처리가 완료되면 Queue에서 메시지를 삭제하는 구조로 되어 있습니다.

2. 문제 상황

SQS의 도입을 시도한 이유는 당시에 제안을 처리하던 과정과 관련이 있습니다.
1. 광고주가 인플루언서에게 제안을 보내면 해당 내용이 DB에 저장된다 2. 운영팀에서 제안을 확인해 기준에 맞는 제안을 승인한다(status를 변경하여 저장) 3. Eventbridge를 통해 주기적으로, 승인된 && 아직 이메일을 보내지 않은 제안을 찾아 인플루언서에게 보낸다
위와 같은 방식은 제안의 숫자가 적을 때는 문제 없이 동작하지만 제안의 개수가 늘어날수록 여러가지 문제가 예상되었습니다.
먼저, AWS Lambda(이하 Lambda)의 timeout 문제입니다. Eventbridge는 Lambda를 트리거해 제안을 찾고 이메일을 보내도록 설계 했지만, Lambda는 15분의 시간제한이 있기 때문에 제안의 개수가 많아지면 일부는 처리되지 못한 채 중단됩니다. 이로 인해 제안이 계속 쌓이게 되고, 인플루언서에게 전송하는데 시간이 오래 걸리는 문제가 발생합니다.
다음으로 동기적(synchronous) 작업으로 인한 속도 저하입니다. DB에서 filter한 제안 object의 list를 반복문을 돌면서 순차적으로 이메일을 보내는 상황에서, 제안의 내용이 많아 용량이 큰 경우 전송 속도가 저하되고 이 때문에 다른 제안이 전송되지 못할 우려가 있었습니다.
위의 문제를 한번에 해결하기 위해 고민한 결과, SQS를 사용하는 것이 가장 적절하다는 판단하에 이를 적용하기 위한 준비를 시작했습니다.

SQS 도입 여정

1. 아키텍처

SQS가 적용되면서 변경된 절차는 다음과 같습니다.
1.
Eventbridge를 통한 CRON으로 이메일을 처리하는 대신, 제안이 승인되면 바로 해당 제안의 정보를 DB에 저장하는 한편 SQS Queue로 보내도록 했습니다.
2.
Queue에 메시지가 들어가면 미리 이메일을 보낼 수 있도록 설정해 놓은 Lambda를 트리거하여 이메일을 보냅니다.
3.
만약 어떤 이유로든 이메일 전송이 실패하면 메시지는 Queue로 돌아가 사전에 설정한 횟수만큼 재시도 합니다.
4.
설정한 횟수 이상 실패하는 경우에는 Dead Letter Queue(DLQ)에 메시지를 이동합니다.

2. 세팅

기본적인 세팅에 대해서는 공식문서에도 자세히 나와 있기 때문에 여기서는 설정하면서 잘 몰랐던 부분이나 중요한 파라미터 등에 대해서만 짚고 넘어가겠습니다.
Standard vs. FIFO Queue 메시지가 처리되는 순서가 중요하거나, 반드시 한 번만 실행되어야 한다면 FIFO Queue가 적합합니다. 유하의 경우 순서는 크게 중요하지 않았기 때문에 standard로 설정하였습니다.
Visibility timeout Queue에 있는 메시지는 소비자가 처리해야 비로소 삭제됩니다. 그래서 처리중에는 메시지가 Queue에 남아있게 되는데, 이 때 다른 소비자가 메시지를 가져가지 못하도록 visibility timeout을 설정합니다.
Message retention period 메시지가 Queue에서 얼마나 있을 수 있는지 설정합니다. 너무 짧을 경우, 메시지가 처리되지 못하고 Queue에서 삭제될 수 있습니다.
Dead Letter Queue Queue를 설정할 때, DLQ는 기본적으로 설정되지 않으므로 함께 설정해 주어야 합니다. 이 때, Dead Letter Queue라는 카테고리가 따로 있는 것이 아니고, Queue를 생성한 후(FIFO는 DLQ도 FIFO로 설정) 이를 DLQ로 지정하면 됩니다. 또한 Maximum receives 파라미터를 통해 설정한 횟수를 초과했을 때 DLQ로 이동하도록 할 수 있습니다.

3. 발견한 문제와 해결 방법

Batch size 관련 문제(Lambda에서 설정) SQS가 Lambda를 트리거하면 Queue안의 메시지를 batch로 가져오게 됩니다. 이 때 batch size를 2 이상으로 설정하게 되면, 한번에 여러 메시지를 가져와서 처리합니다. batch size가 크면 클수록 Lambda를 호출하는 횟수가 적어지므로 비용을 절감할 수 있지만, 중간에 하나라도 실패하게 된다면 batch 전체(성공한 것 포함)가 다시 Queue로 돌아가 처음부터 실행되므로 중복 처리될 위험이 있습니다. 따라서 유하에서는 batch size를 1로 설정해 한 번에 하나의 메시지만 처리하도록 하였습니다.
Visibility Timeout 관련 문제 SQS를 적용한 코드를 배포하고 테스트했을 때, 처음에는 Visibility Timeout을 너무 짧게 설정하는 바람에 이메일을 보내기도 전에 메시지가 Queue로 다시 올라와서 중복으로 이메일을 전송하는 실수가 있었습니다. 그리고 시간을 길게 주었을 때는 이메일 전송이 실패하는 경우, 다시 처리되기까지 시간이 지나치게 오래 걸렸습니다. 몇 번의 시도 끝에 적절한 시간을 찾기는 했으나, 실행하려는 작업의 수행시간을 고려해 Visibility Timeout을 설정해야 합니다.

4. 남은 작업

DLQ로 이동한 메시지 처리
대량으로 이메일을 보내게 되면 일부 메시지가 DLQ로 이동하는 경우가 있습니다.
이렇게 DLQ로 간 메시지는 내용을 확인해 어떻게 처리할지를 정해야 하는데, 현재 DLQ로 이동했을 때 이를 알려주는 수단이 없어, 직접 SQS 콘솔에서 DLQ에 어떤 메시지가 있는지 확인해야 하는 번거로움이 있습니다. 조만간 이를 개선하여 DLQ로 메시지가 이동할 시 알림을 보내 문제의 원인과 메타데이터를 알려주는 기능을 추가할 예정입니다.

마치며

1. 소감

AWS의 서비스에 관한 지식이 부족한 상태에서, 처음으로 초기 구현부터 맡아 업무를 진행하게 되어 실수도 많았고 부족한 점도 많았던 프로젝트였습니다.
하지만 다행히 지금까지 큰 문제 없이 이메일 전송 서비스가 돌아가고 있고, 특히 제안 외의 유하 서비스에서도 이메일 전송기능을 SQS로 통합할 수 있게 되어 만족스럽습니다.
또한 프로젝트를 계기로 AWS 서비스와 아키텍처에 대해 관심을 갖게 되어 관련 자격증을 취득할 동기부여가 되기도 하였습니다.

저자소개

김지훈은 현재 유하의 Back-end 개발자로 일하고 있습니다. 비전공자이긴 하지만 지속적인 자기 개발덕에 훌륭하게 현재 주어진 일들을 잘 수행하고 있습니다. 현재까지는 주로 Python을 써오고 있습니다.

Reference