Amazon SNS(Simple Notification Service)

- 메시지 하나를 여러 수신자에게 보낼거다.
직접 통합(Direct integration)을 쓸 수 있다.
- 구매 서비스 애플리케이션으로 예를 들어보면
이메일 알림을 보내고 사기 탐지 서비스와 배송 서비스, SQS 대기열에 메시지를 보낸다.
그러나 수신 서비스를 새로 추가할 때마다 통합을 생성하고 작성해야 하기 떄문에 번거롭다.
- 그렇기 때문에 Pub/Sub(게시/구독)이란 것을 사용하자.
이를 통해 구매 서비스가 메시지를 SNS 주제로 전송할 수 있다.
-> 메시지를 주제로 게시하는 것.
- 해당 주제에는 많은 구독자가 있으며
- 각 구독자는 SNS 주제에서 해당 메세지를 수신하고 이를 보관할 수 있다.

- 이벤트 생상자
한 SNS 주제에만 메세지를 보낸다.
- 이벤트 수신자(구독자)
해당 주제와 관련한 SNS 알림을 받으려는 사람들.
-> SNS 주제 구독자는 해당 주제로 전송된 메시지를 모두 받게 된다.
- 메세지를 필터링하는 기능을 사용하는 경우에도 메세지를 받을 수 있다.
- SNS는 주제별로 최대 1,200만 이상의 구독자 가능.
- 계정당 가질 수 있는 주제 수는 최대 10만개
- SNS에서 구독자에게 게시할 목록
- SNS -> 이메일
- SNS -> SMS 및 모바일 알림
- SNS -> 지정된 HTTP/HTTPS 엔드포인트
- SNS -> SQS 대기열
- SNS -> 람다 함수
- SNS -> Firehose
SNS는 다양한 AWS 서비스에서 데이터를 받을 수 있다.

- AWS에서 알림이 발생하면 이러한 서비스가 지정된 SNS 주제로 알림을 보냄
SNS 게시 방법(how to publish)
- 주제 게시
SDK 사용해 SNS에 메시지를 게시할 수 있다.
(ㄱ) 주제를 만든다.
(ㄴ) 하나 또는 여러 개의 구독을 만들고
(ㄷ) SNS 주제에 게시
-> 이제 모든 구독자가 자동으로 해당 메시지를 받게 된다.
- 직접 게시(모바일 앱 SDK 전용)
(ㄱ) 플랫폼 애플리케이션을 만든다.
(ㄴ) 플랫폼 엔드 포인트를 만든다.
(ㄷ) 플랫폼 엔드 포임트에 게시
- 수신 가능 대상
google, GCM, Apple APNS, Amazon ADM
-> 모두 모바일 애플리케이션으로 알림을 수신하게 된다.
SNS - 보안
SQS와 동일
- 암호화
- HTTPS API로 전송 중 암호화
- KMS 키를 사용해 저장 데이터 암호화
- 클라이언트가 SNS에 암호화된 메시지를 보내려는 경우를 위한 클라이언트 측 암호화
- 액세스 제어: IAM 정책 중심
모든 SNS API가 IAM 정책으로 규제
- SNS 액세스 정책(S3 버킷 정책과 유사)
- SNS 주제에 교차 계정 액세스 권한을 갖음.
- S3 이벤트와 같은 서비스가 SNS 주제에 작성할 수 있도록 허용
SNS + SQS - Fan Out 패턴
다수의 SQS 대기열로 메세지를 보내려 할 때 모든 SQS 대기열에 개별적으로 전송하려 하면 문제가 발생
애플리케이션에서 충돌이 발생해 전송실패 또는 SQS 대기열을 더 추가하게 되는 경우 등등..
-> 이럴때 필요한게 Fan Out 패턴
- 개념
SNS 주제로 한 번 메시지를 전송하고, 원하는 만큼 SQS 대기열을 SNS 주제에 구독시키는 것.
-> 대기열들은 구독자이고, SNS로 보내진 메세지들을 모두 받을 수 있다.
- 완벽한 분리 모델이고, 데이터 손실이 없다.
- SQS로 데이터 지속성, 지연 처리, 작업 재시도 등의 효과를 얻을 수 있다.
- 이 패턴으로 시간이 지날 수록 SQS 대기열을 SNS 주제의 구독자로 더 추가할 수 있다.
-> 그럴기 위해서 SQS 대기열 접근 정책을 SNS 주제가 SQS 대기열에 쓰기할 수 있도록 허용해야 함.
- 교차 리전 배송
한 리전의 SNS 주제가 다른 리전의 SQS 대기열에 메세지를 보낼 수 있다.
-> 보안 허용 해줘야함.

(ㄱ) 어떤 물건을 구매했을 때 두 개의 대기열로 메세지를 전송하고 싶다.
(ㄴ) 각각 전송하는 대신, SNS 토픽에 한 개의 메시지를 전송하고
(ㄷ) 대기열 두 개가 SNS 토픽을 구독하고 있을 경우
(ㄹ) 사기탐기(Fraud Detector)서비스와 배송 서비스가 각각 자신의 SQS 대기열에서 메세지를 읽을 수 있다.
활용 사례 (1)
- S3 이벤트를 여러 개의 대기열로 보낼 때
S3 이벤트 규칙엔 제한이 있는데
예를 들어 객체가 생성되고 객체의 접두사가 images/ 처럼 이벤트 형식이 조합될 경우 오직 한 개의 이벤트 규칙만 존재 가능하다.
- 여러 개의 대기열로 동일한 S3 이벤트 알림을 보내고 싶다면?
Fan Out 패턴을 사용

(설명)
(ㄱ) S3 버킷에 객체가 생성되어 이벤트가 발생했을 때
(ㄴ) 이벤트를 SNS 토픽으로 전송하고
(ㄷ) 여러 개의 대기열이 SNS 토픽에 Fan Out 패턴으로 구독하게 하면 된다.
이런 Fan Out 패턴을 사용해 이메일이나 람다 함수 등 다른 형식의 애플리케이션도 SNS 주제를 구독해
S3에서 일어나는 이벤트에 대한 메세지를 각각의 목적지로 안전하게 전송됨.
활용 사례 (2)
- Kinesis Data Firehouse를 통해 SNS에서 S3로 직접 데이터를 보내기

(설명)
(ㄱ) SNS가 KDF(Kinesis Data Firehouse)와 직접적으로 통합되어있기 떄문에
(ㄴ) 구매 서비스가 SNS 주제로 데이터를 전송할 수 있고
(ㄷ) KDF가 그 정보를 받을 것이다.
(ㄹ) 그럼 KDF에서 S3 버킷으로 보낼 수 있다.
또는 지원되는 KDF 특정 목적지 어디든 가능하다.
(ㅁ) SNS 주제에서의 메세지들이 계속되게 하고 싶을때 이렇게 전송 범위가 늘어날 수 있다.
SNS - FIFO
- SNS에는 FIFO 기능이 있다.
주제에 순서를 매긴다.

- 개념
(ㄱ) SQS 표준과 FIFO 대기열 모두 구독자가 될 수 있다.
(ㄴ) 제한된 처리량을 갖는다.
(ㄷ) SQS FIFO와 같은 기능을 갖는다.
- 메세지 그룹 ID에 따라 메시지를 정렬하고
- 중복된 ID나 콘텐츠에 대해 중복 제거 가능
SNS FIFO Fan Out이 왜 필요할까?

SQS FIFO를 통해 Fan Out을 할 때는 Fan Out, 정렬, 중복제거가 필요하기 때문이다.
- 구매 서비스는 SNS FIFO 토픽으로 데이터를 보낼 것이고
- 그것은 두 개의 SQS FIFO 대기열로 Fan Out 될 것이다.
- 그러면 사기 탐지 서비스와 배송 서비스가 FIFO 대기열을 읽을 수 있게 된다.
SNS - 메세지 필터링
- 메세지 필터링 기능
JSON 정책으로 SNS 주제 구독자들에게 전송할 메세지를 필터링
- 만약 구독에 필터링 정책이 없다면
기본적으로 무든 메세지를 수신한다.
메세지 필터링 정책 설정

(설명)
(ㄱ) 구매 서비스가 SNS 토픽으로 거래 내용을 전송한다.
거래 내용에는 주문 번호, 제품명, 수량, 현재 상태 등이 있다.
(ㄴ) SQS 대기열을 생성해, 모든 주문이 아닌 발주된 주문만 처리하도록 SQS 대기열을 SQS 주제로 구독
(ㄷ) JSON 필터링 정책을 적용한다.
(ㄹ) 그리고 상태를 '발주됨'으로 정책에 명시
(ㅁ) 그러면 정책에 부합하는 메시지만 SQS 대기열로 들어가게 된다.
(ㅂ) 최소된 주문에 대한 SQS 대기열도 있을 수 있다
-> 취소된 주문에 적용할 필터링 정책을 생성해 같은 SNS 주제에서 SQS 대기열로 가도록 한다.
이것으로 발주된 주문과 취소된 주문의 SQS 대기열은 동일한 메세지를 받지 않게 된다.
+
(ㅅ) 취소 주문 필터링 정책을 사용해 취소된 주문을 위한 이메일 구독을 생성할 수 있다.
(ㅇ) 또 다른 SQS 대기열에 거절된 주문을 위한 필터링 정책도 만들 수 있다.
(ㅈ) 아니면 필터링 정책이 없는 SQS 대기열을 만들어 SNS 주제로부터 모든 메세지를 받도록 할 수 있다.
이런 Fan Out 패턴, 메시지 필터링, FIFO 대기열, FIFO 토픽을 사용하면 다양한 경우를 만들 수 있다.
SNS - 실습
(ㄱ) 주제 생성하기(이름) -> 선택지 선택(FIFO, Standard) -> 이름 설정(FIFO의 경우 이름을 .fifo로 설정) -> 액세스 정책 설정(S3 버킷이 SNS 주제로 이벤트를 전송하도록 설정 가능)
(ㄴ) 구독 생성 -> 프로토콜 선택(Kinesis,SQS,람다,이메일, HTTP/S,SMS등) -> 엔드포인트 설정(여기선 이메일 작성)
(ㄷ) 인증 절차 진행
설정한 이메일로 들어가 구독 승인
추가로 구독 필터링 정책 설정할 수 있다.
- 팬아웃 패턴
(ㄱ) 구독 생성 -> SQS 선택
(ㄴ) 다양한 대기열을 SNS 주제를 구독하는 수신자로 설정