[AWS] Service Communication — AmazonSNS

birdgang
13 min readJan 3, 2024

--

amazonSNS

Amazon SNS 에 대해 얘기해 봅시다.

1개의 메시지를 여러 수신자에게 보내고 싶은 경우에 이렇게 직접 연결할 수 있습니다.

예를 들면 Buying Service 는 Email notification 을 보낼 수 있고, Fraud Service 를 전송할 수 있고, Shipping Service 에 메시지를 보낼 수 있으며, SQS 대기열에도 보낼 수 있습니다.

이 작업은 꽤 번거롭습니다, 새로운 수신서비스를 추가해야 할 때마다, 이런 연결을 만들고 작성해야 하기 때문이죠. 대신, 이렇게 Pub/Sub 즉 publish 와 Subscribe 를 호출할 수 있습니다.

개념을 보면, Buying Service 는 메시지를 토픽에 퍼블리싱해 주는 SNS Topic에 메시지를 보내고 토픽은 수많은 구독자를 갖고 있고, 각각의 구독자들은SNS 토픽으로부터 메세지를 받을 수 있으며 그 메시지를 자신들의 것으로 만듭니다. 그래서 이것은 Pub/Sub 이라는 또다른 타입의 패턴입니다.

Amazon SNS 에서 event producer 는 하나의 SNS Topic 에게만 메시지를 보내고, SNS Topic 이 event Receivers 또는 Subscriptions 에게 통지하게 됩니다. 따라서 SNS Topic 에 있는 각각의 구독자들은 필터 기능을 사용하여 메시지를 필터링 하는 경우를 제외하면 해당 topic 으로 전송된 모든 메시지를 받게 됩니다. 그리고 그것 또한 가능합니다.

그러면 토픽별로 얼마나 많은 구독자를 가질 수 있을까요? 토픽별로 1,250만 까지 구독이 가능합니다, 꽤 많죠? 여러분의 계정에서는 최대 10만 개의 토픽을 얻을 수 있지만 그 한도는 늘릴 수 있고 이 부분은 변경될 수 있습니다.

SNS 의 경우에 여러분은 구독자 들에게 퍼블리시 하게 되는데요. 무엇을 퍼블리시 할 수 있을까요?

SNS 에서 직접 이메일을 보내고, SMS 나 모바일 알림을 보낼 수 있습니다. 또한 특정 HTTP 나 HTTP 엔드 포인트에 데이터를 전송할 수도 있습니다. 게다가 SQS 와 같은 AWS서비스와 통합되어 특정 기능을 하는 Lambda 의 대기열로 보내서 메시지를 받은 다음에 어떤 코드를 처리 하라고 할 수도 있고, 아니면 Amazon S3나 Redshift 에 데이터를 보내기 위해 Kinesis data firehose 로 보낼 수도 있습니다.

SNS integrates with a lot of AWS services

여기에 더해 SNS 는 수많은 AWS 서비스로 부터 데이터를 받습니다, 데이터를 SNS 에 직접 보냅니다.

CloudWatch 알람, 오토 스케일링 그룹, CloudFormation, AWS Budgets, S3 Bucket, AWS DMS, Lambda, DynamoDB, RDS Events 등에 보내는데 전부 기억할 필요는 없습니다. 하지만 AWS 내에서 어떤 알림사항이 발생하면 즉시 지정된 SNS 토픽으로 알림을 전송합니다.

Amazon SNS — How to publish

그렇다면 SNS 는 어떻게 작동할까요?

메시지를 publish 하기 위해 Topic Publish 를 사용합니다. 토픽을 생성한 다음 1개 또는 여러 개의 subscription 을 생성하고 SNS topic에 퍼블리시합니다. 이게 전부입니다. 모든 구독자들은 그 메시지를 자동으로 검색해서 가져옵니다.

또는 모바일 앱 SDK 위한 Direct Publish 가 있는데요, 플랫폼 애플리케이션을 생성한 다음 플랫폼 엔드포인트를 생성하고 그 플랫폼 엔드포인트에 퍼블리시합니다. 모바일 애플리케이션 알림을 수신하는 다양한 방법인 구글의 GCM, 애플의 APNS, 아마존의 ADM 등의 구독자 측면에서 작동합니다.

Amazon SNS — Security

보안측면에서 보면 아마존 SNS 는 SQS 와 동일한 종류의 보안체계를 갖고 있으며, 기본적으로 In-flight encryption 을 사용하며 At-rest encryption 은 KMS keys 를 사용합니다, 클라이언트 측면에서 암호화는 만약 클라이언트가 암호화된 메시지를 SNS 에 보내고 싶다면 암복호화 수행은 클라이언트의 책임입니다.

액세스 제어 부분에서 보면 IAM 정책이 보안의 중심이 되는데요, 모든 SNS API 는 그 정책에 따른 규제를 받기 때문입니다. SNS 접근 정책은 S3 Bucket 정책과 아주 유사한데, SNS 주제에 접근하기 위해 교체 계정을 원한다거나 토픽에 작성하려는 S3 이벤트와 같은 다른 서비스를 허용하고 싶은 경우에 매우 유용합니다.

SNS + SQS: Fan Out

자, 이제 SNS + SQS 의 fan-out 패턴에 대해 알아봅시다.

이것은 다수의 SQS 에게 메시지를 전송하고 싶지만, SQS 대기열에 있는 모두에게 개별적으로 보낸다면 이와 관련한 문제가 생길 수도 있는 경우를 위한 것입니다.

예를 들면 애플리케이션 간의 충돌 또는 배달 오류 아니면 더 많은 SQS 대기열을 추가하는 경우도 있을 겁니다.

그래서 이 마지막 패턴을 사용하려고 합니다.

일단 SNS 에서 토픽을 푸시 하면, SQS 대기열에 있는 구독자 들은 원하는 만큼의 SNS 토픽을 구독하게 되는 것입니다. 이 대기열이 구독자 이며 모두 SNS 로 전송된 메시지를 수신합니다.

예를 들어 Buying Service 가 있는데 2개의 SQS 대기열에 메시지를 보내고 싶다고 하면 대신 SNS topic 에 메시지를 보낸 다음, SNS 토픽에 메시지를 하나 보내면 SQS 대기열에 있는 구독자인 Fraud Service, Shipping Service 는 자신들의 SQS 로부터 받은 메시지를 읽게 됩니다.

이 모델에 대한 개념 또한 완벽한 분리 모델이고 어떤 데이터 손실도 없습니다. SQS 는 데이터 영속성, 지연 처리, 작업에 대한 재시도 를 제공 하는데요. 이 패턴을 통해 시간이 지남에 따라 더 많은 SQS 를 SNS 토픽의 구독자로 추가할 수 있습니다.

이를 위해서, 전에 살펴본 것처럼 SNS 토픽이 SNS 대기열에 쓸 수 있도록 SQS 대기열 액세스 정책이 허용해야 합니다. 액세스 정책사용을 위한 또 다른 사용 사례가 있습니다, Cross-Region Delivery 가 그것인데요. 한 지역의 SNS 토픽은 다른 지역의 SQS 에 메시지를 보낼 수 있습니다. 보안이 허락한다면 말이죠.

Application: S3 Events to multiple queues

다음으로는 다른 목적을 위해 이 패턴을 어떻게 사용할 수 있을까요?

예를 들면 S3 이벤트를 다수의 대기열에 보내는 애플리케이션이 있습니다.

S3 이벤트 규칙에는 제한사항이 있습니다. 예를 들면 객체를 생성하는 event type 과 images/같은 접두사 들의 조합을 말하는데요. S3 이벤트 규칙은 오직 1개만 가질 수 있습니다. 하지만 만약 동일한 S3 이벤트 알림을 다수의 대기열에 보내고 싶다면 어떻게 할까요?

그런 경우에 fan out 패턴을 사용하면 됩니다.

예를 들어 S3 버킷에 이벤트로 생성된 S3 객체가 있고 이 이벤트를 SNS 토픽에 보냅니다. 그러면 SNS 토픽을 구독하는 SQS 대기열에 fan out 으로 메시지를 보낼 것입니다. 하지만 다른 타입의 애플리케이션인 email, Lambda functions 등도 구독할 수 있습니다. 여기서 우리가 얻을 수 있는 것은 아마존 S3에서 벌어지는 이벤트 메시지가 fan out 패턴 덕분에 다양한 목적지로 가게 된다는 것입니다.

Application: SNS to Amazon S3 through Kinesis Data Firehose

SNS 로 부터 아마존 S3에 직접 데이터를 보내는 또다른 아키텍쳐로는 Kinesis Data Firehose 가 있습니다.

SNS 는 KDF 와 직접 연결되는 형태이기 때문에, buying service 는 SNS 토픽에 데이터를 보낼 수 있고 Kinesis data firehose 즉 KDF 는 그 정보를 받게 될 것입니다. 그런 다음 Kinesis data firehose 에서 아마존 S3 버킷 또는 지원되는 모든 KDF 를 대상으로 전송합니다, 이런 방식을 사용하면 SNS 토픽 으로부터 메시지를 유지하고 싶은 방식으로 확장할 수 있습니다.

Amazon SNS — FIFOTopic

또한 이 패턴을 FIFO 토픽에도 적용할 수 있습니다. 아마존 SNS 에는 메시지 순서를 지정하는 FIFO 즉 선입 선출 방식의 기능이 있습니다.

그래서 프로듀서는 메시지 1,2,3,4 를 구독자에게 보낼 수 있고 구독자는 SQS FIFO 대기열에 따라 메시지를 1,2,3,4 순서대로 수신할 수 있습니다.

SNS FIFO 에 대한 개념은 SQS FIFO 기능과 동일합니다. 메시지 Group Id 에 따라 정렬 되며, Deduplication ID 또는 내용 기반의 중복 제거를 통해 중복되는 데이터를 제거합니다, 하지만 구독자들은 SQS FIFO 토픽만 가질 수 있습니다. 처리량을 놓고 보면, 한도가 있습니다.

SQS FIFO 대기열과 동일한 처리량을 얻게 되는데, SNS FIFO 토픽의 메시지만 읽을 수 있기 때문입니다.

SNS FIFO + SQS FIFO: Fan Out

그렇다면 이런 것들이 필요한 이유는 뭘까요?

SQS FIFO 를 사용해서 fan out 을 하고 싶기 때문입니다, 그래서 Fan out, 정렬, 중복 데이터 제거가 필요합니다.

Buying Service 는 SNS FIFO Topic에 데이터를 보내면 2개의 SQS FIFO 대기열에 있는 Fraud Service와 Shipping Service 에 fan out 하게 되고 SNS FIFO Topic 에 있는 메시지를 읽게 됩니다.

SNS — Message Filtering

SNS 의 마지막 기능은 fan out 패턴과 관련된 아주 편리한 기능인데요, SNS에서 메시지를 필터링하는 기능입니다.

메시지 필터링이란 무엇일까요? SNS 토픽 구독으로 전송되는 메시지를 필터링 하는데 사용되는 Json 정책입니다. 그래서 만약 구독에 필터링 정책이 없다면, 모든 메시지들을 수신하게 되고 그것이 기본방식이 됩니다.

메시지 필터링 정책을 설정할 때 어떤 일이 벌어지는지 예를 들어 보겠습니다.

Buying Service가 있고 SNS 토픽에 새로운 트랜젝션을 보냅니다.

예를 들면, 트랜젝션 내용은 주문번호가 있고, 제품은 연필이고 수량은 4개 그리고 발주된 상태입니다. 여기서 우리는 SQS 대기열에 발주된 주문만 포함하고 싶습니다, 모든 주문이 아니라 발주된 것만요.

이를 위해 SNS 토픽에 SQS 대기열이 구독하게 하고, Json 으로 필터링 정책을 적용할 것입니다. 우리는 그 정책에서 상태는 발주된 상태를 원한다고 정책을 명시할 것입니다. 따라서 정책에 부합하는 메시지만 SQS 대기열로 가게 됩니다, 하지만 SQS 대기열 에는 취소된 주문이 있기 때문에, 취소된 주문에 대한 필터링 정책을 생성할 수 있습니다, 이런 것들은 모두 같은 SNS 토픽에서 SQS 대기열로 오게 됩니다. 따라서 발주된 주문과 취소된 주문을 받는 SQS 대기열은 각각 다른 메시지를 받습니다.

또한 취소된 주문에 대한 이메일 구독 생성을 위해 취소 주문에 대한 동일한 필터링 정책을 사용할 수 있습니다. 또한 SQS 대기열에 거절된 주문에 대한 필터링 정책도 가질 수 있습니다. 아니면 필터링 정책없이 모든 SNS 토픽에 있는 메시지를 수신하는 SQS 대기열을 생성할 수도 있습니다.

이런 모든 fan out 패턴과 메시지 필터링, FIFO 대기열 그리고 FIFO 토픽 등을 사용하면, 아주 다양한 가능성을 얻을 수 있습니다.

SNS — Message Delivery Retries

메시지 전송 재시도 와 SNS Dead Letter Queue 에 대해 좀더 깊이 알아봅시다.

메시지가 SNS 구독자에게 배달될 때, 만약 서 쪽의 오류인 경우에는 배달 정책이 적용됩니다. 이것은 SNS 가 호출하는 엔드포인트에 문제가 있다는 것을 의미합니다, 이 테이블은 어떤 일이 발생할 것처럼 만든 것인데요.

AWS Managed endpoints 를 보면 KDF, Lambda, SQS가 있습니다, immediate retry를 보면 배달 오류 발생시 즉시 3 회 재시도 하게 되어 있습니다. 그러면 아마 메시지는 전송될 것입니다.

만약 발송 되지 못하면, Pre-backoff 단계로 넘어가는데요, 1초 간격으로 2번 시도하게 됩니다. 그런 다음 backoff 단계로 가는데 여기서는 10회 시도하는데 1–20초 범위에서 지수 백오프를 사용합니다. 그래도 실패했다면, post-backoff 단계로 가는데 여기서는 20 초 간격으로 10 만회 시도합니다. 그래서 전체 23 일동안 100,015 회를 시도하게 됩니다.

보다시피, AWS Managed endpoints 에서는 수많은 재시도 가 이루어집니다. SNS-메시지 전송 재시도에는 또다른 방법이 있는데요. 여기서 아이디어는 Delivery 정책이 있고 메시지 전송이 성공적일 때까지 재시도 한다는 것입니다.

SNS — Custom Delivery Policies

Http 엔드포인트가 있는 경우, SNS 토픽에 구독자를 설정한 다음 맞춤 정책에 대해 지원합니다.

재시도 횟수는 몇 번인지, 최소 지연과 최대 지연은 얼마인지, 그리고 백업 기능, 스로틀 정책 등 백엔드는 과부화 또는 수많은 재시도를 원치 않을 수도 있기 때문에 SNS가 백엔드에 대해 재시도하는 방법에 대해 정의합니다.

이것은 사용자 지정 Delivery 정책을 지원하는 유일한 종류의 Delivery 매커니즘 입니다, 아주 중요한 내용 이므로 꼭 기억하시기 바랍니다.

SNS — Dead Letter Queues

자, 다음은 Dead Letter Queues입니다.

배달 정책을 모두 적용 했지만 메시지가 배달되지 못한 경우에 Dead Letter queue 를 설정하지 않았다면 메시지는 폐기될 것입니다.

DLQ 는 우리가 SQS 를 갖는 것과 유사한 것인데 DLQ 는 SQS, 또는 SNS FIFO를 사용하는 경우에는 SQS FIFO 와 마찬가지로 토픽이 아닌 구독에 첨부됩니다.

확실하게 정리해 볼께요, SNS 토픽이 메시지를 받고, 2개의 구독이 있는데 하나는 이메일 구독 이고, 또 하나는 http 구독입니다, 그리고 이런 것들이 어떻게 이슈사항을 갖는지 알 수 있습니다.

예를 들어 이메일 서버에 이슈가 생기면 문제가 발생할 수 있고, http 구독에 이슈가 생겨도 문제가 발생할 수 있습니다. 따라서 이메일 구독을 위해 Dead Letter Queue 를 설정할 수 있고 Http 구독을 위해 Dead Letter Queue 를 설정할 수 있습니다, 따라서 그런 일이 발생해서 배달이 성공적 이지 못한 경우에 메시지 처리를 보장할 수 있습니다.

--

--