gony-dev 님의 블로그

Section 19. AWS Integration & Messaging - 1 본문

AWS

Section 19. AWS Integration & Messaging - 1

minarinamu 2024. 10. 22. 13:16
여러 개의 어플리케이션을 배포하려고 할 때, 어플리케이션들은 서로 소통을 해야할 필요가 있다.

여기 두 가지의 어플리케이션 의사소통 패턴이 있다.
1. Synchronous communications
- 어플리케이션이 또 다른 어플리케이션과 직접 연결된다.
- 예시로 구매 서비스와 배송 서비스의 직접적인 연결이 있다.

2. Asynchronous / Event based
- 미들웨어가 어플리케이션을 연결한다. 직접적으로 연결되어 있지 않다는 의미이다.
- 위와 같은 예시로 구매 서비스가 'queue'라는 대기열에 메시지를 전달한다. 그러면 배송 서비스는 대기열에게 구매 내역을 물어보고 메시지를 받아 행동을 취한다.

Amazon SQS

SQS의 핵심은 대기열이다.
SQS 대기열에는 메시지를 포함하며, 메시지를 담기 위해서는 무언가 SQS 대기열에 메시지를 보내야 하며, 메시지를 보내는 주체자를 '생산자'라고 한다.
- 생산자는 여러 명일 수 있으며 여러 생산자가 여러 개의 메시지를 SQS 대기열에 보내게 할 수 있다.

메시지는 받는 자는 '소비자'라고 하는데, 대기열에 메시지가 있으면 소비자는 이 메시지를 polling해서 정보를 얻는다.
- 소비자는 메시지로 처리를 하고 대기열에서 메시지를 삭제한다.

Standard Queue

  • 특징
    • 완전 관리형 서비스이고, 어플리케이션을 분리하는데 사용된다.
    • 무제한적인 처리량을 얻을 수 있다.
    • 각 메시지는 수명이 짧은데, 기본값으로 4일에서 14일까지 남아있다. 그동안 처리되지 않으면 소실되기 때문이다.
    • 지연 시간이 짧아서 SQS는 메시지를 보내거나 SQS에서 메시지를 게시 및 수신 시 10ms초 이내로 빠르게 응답을 받는다.
    • 메시지의 크기는 256KB 미만이어야 한다.
    • 메시지는 중복이 있을 수 있다!

SQS - Producing Messages

  • 최대 256KB의 메시지가 생산자에 의해 SQS로 전해진다.
  • SQS에 메시지를 보내는 API를 SendMessage라고 하며, 과정은 메시지가 작성되면 소비자가 해당 메시지를 읽고 삭제할 때까지 대기열에 남아있는다.

SQS - Consuming Messages

  • EC2 인스턴스에서 실행될 수 있다. 원할 경우 온프레미스나 Lambda에서도 가능하다.
  • 소비자가 polling하는 메시지는 최대 10개이다.
  • 메시지에 대한 행위를 처리한 다음에는 소비자가 DeleteMessage API로 대기열에서 삭제한다. 그러면 다른 소비자가 이 메시지를 볼 수 없게 된다.

SQS with ASG

    • ASG는 SQS를 사용하는 완벽한 사례로 적용된다. 아래 예시를 통해 확인하자.

대기열의 길이가 특정 수준을 넘어가면 알람이 용량을 x만큼 증가시킨다.

 

SQS to decouple between application tiers

  • SQS는 어플리케이션 계층 간에 분리를 위해서 사용된다.
  • 아래의 비디오를 처리하는 어플리케이션의 예시를 보자.

2개의 계층을 사용하여 비디오를 처리한다.

SQS - Security

  • 암호화
    • HTTPS API를 사용하여 메시지를 보내고 생성하면서 In-flight 암호화를 실시한다.
    • KMS 키를 사용하여 미사용 암호화를 얻는다.
    • 원한다면 클라이언트 측 암호화도 실행할 수 있는데 이는 클라이언트가 암호화 및 암호 해독을 수행 가능해야 할 수 있다.
  • 액세스 제어
    • SQS API에 액세스를 규제하기 위해 IAM 정책을 사용한다.
  • SQS 액세스 정책(similar to S3 bucket policies)
    • SQS 대기열에 대한 교차 계정 액세스를 수행하려는 경우
    • SNS 같은 다른 서비스가 SQS 대기열에 S3 이벤트 같은 것을 쓸 수 있도록 허용하려는 경우에 유용하다.

SQS Queue Access Policy

S3 버킷 정책과 매우 유사한 SQS queue 액세스 정책에 대해 알아보자.

두 가지의 이용 사례가 있는데 이를 알아보자

 

1. Cross Account Access

  • 어떤 계정에 대기열이 있고 다른 계정이 그 대기열에 액세스해야 한다고 가정해보자.
  • 계정 간 메시지르르 가져오기 위해서는 대기열 액세스 정책을 생성하고, 첫 번째 계정의 SQS 대기열에 첨부를 해야한다.

2. Publish S3 Event Notifications To SQS Queue

  • SQS 대기열에 자동으로 메시지를 보낸다.

SQS - Message Visibility Timeout

메시지 가시성 초과는 소비자가 메시지를 polling하면 , 그 메시지는 다른 소비자에게 보이지 않게 되는 원리이다.
아래 예시를 보자.
기본값으로 메시지 가시성 시간 초과는 30초로 다른 소비자가 메시지 요청 API를 호출하면 메시지가 반환되지 않는다.
하지만 시간 초과가 경과되고 메시지가 삭제되지 않았다면, 메시지는 다시 대기열에 넣는다.
  • 만일, 시간을 더 가지고 싶다면 ChangeMessageVisibility라는 API를 통해 소비자가 시간을 더 확보할 수 있다!
    • 만일 가시성 시간을 높게 설정하고 소비자가 충돌한다면, 메시지가 SQS에 다시 나타날 때까지 몇 시간이 걸린다.
    • 반대로 가시성 시간이 매우 낮다면, 소비자가 메시지를 여러 번 읽어 중복 처리 될 수도 있다!

SQS - Dead Letter Queue (DLQ)

소비자가 정해진 시간 내에 메시지를 처리하지 못했을 경우에는 어떻게 될까?
메시지는 우리가 배웠던 대로 대기열로 돌아가게 되는데 이런 일이 자주 생기면 대기열로 반복해서 돌아갈지도 모르는 문제가 생긴다.

최대 수신 임계값을 설정하면 그 값이 초과한 후에 메시지는 DLQ(실패 메시지 대기열)로 가게 된다.
DLQ는 디버깅 시 아주 유용하다. 메시지가 다른 대기열로 가면 이것 또한 SQS 대기열이라 처리해야 하는데, 그동안 문제를 파악할 시간을 마련할 수 있다.
  • 유의할 사항
    • FIFO 대기열은 DLQ도 FIFO 대기열이여야 한다.
    • 표준 대기열은 DLQ도 표준 대기열이여야 한다.
    • DLQ의 메시지들은 대기열에서 만료되기 전에 처리해야 한다. 약 14일 정도로 설정한다.

SQS DLQ - Redrive to Source

  • 실패 메시지 대기열 관리에 쓰는 또 다른 기능은 소스로 재드라이브이다.
  • DLQ에 있는 메시지를 다시 소비하여 문제를 파악할 수 있게 도와주는 기능이다.
  • 만일 소비자가 받는 코드가 고쳐져서 메시지를 다시 받을 수 있게 되었을 때, DLQ에 있는 메시지를 소스 SQS 대기열로 다시 이동시킬 수 있다!

SQS - Delay Queue

대기열 지연은 소비자들이 즉각적으로 볼 수 없도록 메시지를 지연시키는 것이다.
기본 지연 시간은 0초로 바로 볼 수 있으며, 이 시간을 15분까지 지연시킬 수 있다.
- 모든 메시지를 몇 초만큼 지연시킬 것인지 대기열 레벨에서 기본값을 지정하거나 매번 메시지를 보낼 때마다 DelaySeconds 파라미터를 사용하여 메시지별 지연 시간을 조정할 수 있다.

SQS - Long Polling

소비자가 SQS로부터 메시지를 요청할 때, 만약 대기열이 비어있다면 메시지가 도착할 때까지 기다리도록 할 수 있다.
롱 폴링의 목적은 SQS 대기열로 보내는 API 호출을 줄이는 것이다. 더불어 메시지가 SQS 대기열에 도착하자마자 SQS 대기열이 이를 다시 소비자에게 전송한다.

API 호출을 줄일 수 있기 때문에 효율성을 향상시키게 되고, CPU 연산도 적어지게 된다.
롱 폴링 시간은 1~20초 사이가 될 수 있으며, 보통 20초로 설정한다.
롱 폴링은 대기열 레벨에서 활성화하거나, 소비자가 폴링을 위해 SQS 대기열로 API 호출을 보낼 때 WaitTimeSeconds 파라미터를 사용하여 API 호출 레벨에서 활성화할 수도 있다.

 

SQS Extended Client

  • 최대 메시지 크기 제한이 256KB라는 것을 이미 모두가 알고 있다. 그렇다면, 어떻게 SQS 대기열로 대용량 메시지를 보낼 수 있을까?
  • 이 때, SQS Extended Client Java 라이브러리를 사용한다.
  • 해당 라이브러리는 Amazon S3 버킷을 대용량 데이터를 담는 repository로 사용하는 것이다.
    • 생산자를 대기열로 메시지를 보내는데, 이 메시지 안에 대용량 메시지에 대한 포인터를 가진 작은 메타데이터가 담겨있다.
    • 대기열은 작은 메시지를 포함하고, S3 버킷이 대용량 객체를 포함한다.
    • 소비자는 S3로부터 대용량 메시지를 가져와서 읽을 수 있게 된다.

반드시 알아야할 API들

  • CreateQueue(MessageRetentionPriod) | 대기열 생성
  • DeleteQueue | 대기열 내의 하나의 메시지를 삭제
  • PurgeQueue | 대기열 내의 모든 메시지를 삭제
  • MaxNumberOfMessages | 최대 메시지 개수를 설정(기본값은 1, 최대 10까지 가능)
  • ReceiveMessageWaitTimeSeconds | 롱 폴링 활성화와 같은 맥락
  • ChangeMessageVisibility | 메시지 시간초과를 변경

여러 API 호출을 묶음으로 사용하려면 SendMessage, DeleteMessage, ChangeMessageVisibility를 사용하여 비용을 줄일 수 있다.

 

SQS - FIFO Queue

FIFO는 선입선출이라는 뜻으로 먼저 들어간 메시지가 먼저 나간다는 의미이다.

순서가 보장되는 자료구조 형태라고 보면 된다.

  • FIFO 대기열은 순서에 대한 강제적인 보장이 존재하기에 제한된 처리량을 가진다.
    • 묶음이 아닐 경우에는 초당 300개의 메시지를 처리하고, 묶음으로 보낼 경우에는 초당 3000개가 된다.
  • 중복을 제거하도록 도와주는 FIFO 대기열 기능으로 정확히 한 번만 보낼 수 있게 한다.

SQS FIFO의 심화 개념

1. Deduplication

  • 중복제거가 적용되는 시간은 5분으로, 5분 간격 이내에 동일한 메시지를 두 번 발송할 경우 두 번째 메시지는 거부된다.
  • 중복제거의 방법에는 2가지가 있다.
    1. 내용기반 중복제거 | 메시지 본문에 대해 SHA-256방식 알고리즘을 사용하여 해시가 계산된다.
      • 동일한 메시지 본문이 반복되면 해시 역시 동일하게 두 번 발생한다.
    2. 메시지를 전송할 때 메시지 중복제거 ID를 직접적으로 명시하는 방법
      • 동일한 중복제거 ID가 두 번 반복되면 그 메시지는 거부된다.

SHA-256 알고리즘을 사용하여 해시를 계산하고 동일한 메시지 본문을 제거.

2. Message Grouping

  • SQS FIFO 대기열로 메시지를 보낼 때, 메시지 그룹 ID의 값을 동일하게 정하는 경우, 해당 ID에 대해서 한 명의 소비자만 갖게 된다.
  • 메시지의 서브셋 레벨에서 순서대로 정렬할 필요가 있다면, 메시지 그룹 ID에 대해 다른 값을 정해야 한다.
    • 위의 두 가지 사항으로 공통된 메시지 그룹 ID를 공유하는 메시지는 해당 그룹 내에서 순서대로 정렬된다는 것을 알 수 있다.
    • 각 그룹 ID는 다른 소비자를, 즉 병렬 처리를 할 수가 있다.


Amazon SNS

메시지 하나를 여러 수신자에게 보낸다고 가정하자.
이럴 경우에는 직접 통합을 사용할 수가 있다. 이 경우 수신 서비스를 새로 추가할 때마다 통합을 생성하고 작성해야 하기에 번거로울 수 있다.
그래서 Pub / Sub 패턴을 사용한다.
이 패턴은 하나의 주제에 대해 여러 구독자들에게 전달해주는 개념으로 통합에 최적화 되어 있다.
  • SNS에서는 이벤트 생성자가 한 SNS 주제에만 메시지를 보낸다.
  • 이벤트 수신자(=구독자)는 해당 주제와 관련된 SNS 알림을 받으려고 한다.
  • 따라서 SNS 주제 구독자는 해당 주제로 전송된 메시지를 모두 받게 된다.
  • 최대 구독자 수는 주제별로 최대 1,200만 명까지 가능하다.
  • 계정당 가질 수 있는 주제 주는 최대 10만 개이며 원한다면 늘릴수도 있다.

SNS를 구독하는 구독자들

  • SNS는 다양한 AWS 서비스들에서 메시지를 수신하기도 한다.

 

SNS 게시 방법

  • SDK 주제 게시를 사용해 SNS에 메시지를 게시할 수 있다.
    1. 먼저 주제를 만들고, 하나 이상의 구독을 만든다.
    2. SNS 주제에 게시한다.
  • 직접 게시도 할 수 있다.(모바일 앱 SDK 전용)
    1. 플랫폼 어플리케이션을 만든다.
    2. 플랫폼 엔드 포인트에 게시한다.
    3. 수신 가능 대상은 Google GCM, Amazon ADM

SNS - Security

  • 보안 측면에서 SNS는 SQS와 비슷하다.
  • Encryption:
    • 전송중 HTTPS API를 사용한 암호화
    • KMS 키를 사용한 저장 데이터 암호화
    • 클라이언트가 암호화/복호화를 수행하길 원할 경우의 클라이언트 측면 암호화
  • Access Controls: 액세스 제어는 IAM 정책 중심이다.
  • SNS Access Policies(S3 버킷 정책과 유사)

SNS + SQS: Fan Out

다수의 SQS 대기열로 메시지를 보내려 할 때, 모든 SQS 대기열에 개별적으로 전송하려고 하면 문제가 발생할 수 있다.
이때 Fan Out 패턴을 사용한다.
SNS 토픽으로 한 번 메시지를 전송하고 원하는 만큼 SQS 대기열을 SNS 토픽에 구독시킨다.
이 대기열들은 구독자이며, SNS로 보내진 메시지들을 모두 받을 수 있다.

완전히 분리되어 데이터 손실이 없으며, SQS로 데이터 지속성, 지연처리, 작업 재시도 등의 효과도 얻을 수 있다.
시간이 지날수록 SQS 대기열을 SNS 토픽의 구독자로 더 추가할 수 있다.
그러기 위해서는 SQS 대기열 액세스 정책이 SNS를 쓸 수 있게 확실히 정해야한다.

하나의 SNS 토픽에 2개의 SQS를 구독시킨 모습

 

SNS to Amazon S3 through Kinesis Data Firehose

  • SNS는 키네시스로 보낼 수 있고, 아래의 아키텍쳐를 얻을 수 있다.

SNS - FIFO Topic

  • 들어간 순서대로 전송을 하는 분류 방식
  • SQS FIFO는 메시지 그룹 ID에 따라 메시지를 정렬하고, 중복된 ID나 컨텐츠에 대해 중복제거가 가능하며 SQS 표준과 FIFO 대기열 모두 구독자가 될 수 있다.
  • SNS FIFO + SQS FIFO: Fan out 전략에는 fan out + 정렬 + 중복제거가 필요하다!

SNS - Message Filtering

  • 메시지 필터링이란 'SNS 토픽 구독자들에게 전송할 메시지를 필터링하는 JSON 정책이다.'
  • 만일 구독에 필터링이 없다면 모든 메시지를 수신하게 된다.