애플리케이션을 여러 개 배포하려고 할때 커뮤니케이션을 해야하는데
두가지의 패턴으로 나눠진다

1) 동기 커뮤니케이션(직접 소통)
애플리케이션이 또 다른 애플리케이션과 직접적으로 연결
'누군가 구매를 했다' 직접 배송 서비스에 연락 해 물건 배송
2) 비동기/이벤트 기반 유형(직접 소통x)
대기열 미들웨어가 애플리케이션들을 연결
'누군가 구매를 했다'라는 대기열 큐를 생성 후 물건 배송
- 애플리케이션 간 동기화 문제점
구매가 급증하거나 한 서비스가 다른 서비스를 압도하는 경우
트래픽 급증등 예측 불가할 때
비동기 처럼 분리 계층을 확장하는것이 좋다.
- 종류
- SQS: 대기열 모델
- SNS: pub/sub 모델
- Kinesis: 실시간 스트리밍 모델(대용량 데이터를 다룰때)
-> 이를 통해서 독립적으로 서비스를 확장
SQS(Standard Queue/FIFO Queue)

- 대기열 서비스
SQS 대기열에는 메시지를 포함
생산자: SQS 대기열에 메시지를 보내는 주체
-> 생산자는 하나일수 있고 여러개의 메세지를 보낼 수 있다.
소비자: 대기열엣 메시지를 처리하고 수신해야 하는 대상
-> 소비자는 대기열에서 메시지를 폴링(대기열에 물어봐 해당 소비자에 메시지가 온 게 있는지 확인)
-> 메시지를 처리하면 대기열에서 메시지 삭제
- 즉, 대기열 서비스는 생산자와 소비자 사이를 분리하는 버퍼 역할
SQS - Standard Queue
- 완전 관리형 서비스
애플리케이션을 분리하는데 사용
- 특징
- 무제한 처리량을 얻을 수 있다
초당 원하는 만큼 메시지를 보낼 수 있다.
대기열에도 원하는 만큼 메시지를 포함할 수 있다.
-> 처리량에 제한이 없고 대기열 메시지 수도 제한이 없다.
- 메시지 수명이 짧다
기본값으로 4일동안 남아있고, 최대 14일동안 남아있을 수 있다.
- 지연시간이 짧다
SQS는 메시지를 보내거나 SQS에서 메시지를읽을 때마다 송신/수신 시 10 밀리초 이내로 빠르게 응답을 받는다.
- SQS 메시지는 작아야한다.
256KB 미만이어야 한다.
- SQS는 중복 메시지가 있을 수 있다.
- 최선의 오더: 품절 메시지를 보낼 수 있다.
SQS - Producing Messages(메시지 생산자)

최대 256KB 메시지가 생산자에 의해 SQS로 전송된다.
- 어떻게 보낼까?
(ㄱ) 생산자는 SDK 소프트웨어 개발 키트를 사용해 SQS에 메시지를 보낸다.
-> SendMessage API: SQS에 메시지를 보내는 API
(ㄴ) 메시지가 작성되면 소비자가 해당 메시지를 읽고삭제할 때까지 SQS 대기열에 유지된다.
-> 4~14일 보존
(예시)
패킷과 같은 오더를 처리한 다음 센터로 배송
정보가 포함된 메시지를 SQS 대기열로 보낸다.
-> 오더 ID, 고객 ID와 원하는 속성, 주소 등등..
그러면 애플리케이션 권한에 있는 소비자는 해당 메시지 처리해야 함.
+ 표준 SQS는 처리량이 무제한이다.
SQS- Consuming Messages(메세지 소비자)

소비자는 애플리케이션이다.
이 애플리케이션은 EC2 인스턴스(즉, AWS 상의 가상 서버)에서 실행될 수 있다.
+ 온프레미스 서버에서 실행할 수도있다.
+ 람다 함수에서 실행할 수도 있다.
(예시) 인스턴스에 대한 간단한 사용 사례
(ㄱ) 대기열에는 소비자가 있고 소비자는 SQS 메시지를 폴링한다.
(ㄴ) 소비자는 한 번에 최대 10개의 메세지를 받을 수 있다.
그럼 소비자는 이 메시지에 대해 처리할 책임이 있다.
- ex) RDS DB에 오더를 입력하는 경우
각 오더들을 RDS DB에 삽입하면 메시지들이 수신되어 처리됬기 때문에 RDS DB로 삽입된다.
그러면 소비자가 이 메시지들을 DeleteMessage API로 대기열에서 삭제한다.
그러면 다른 소비자들이 이 메세지를 볼 수 없게 되고 그러면 메시지처리가 완료 된것.
SQS - Multiple EC2 Instances Consumers

소비자를 더 확장해 여러 소비자를 동시에 가질 수 있다
- SQS 대기열은 메세지를 동시에 수신하고 처리할 소비자를 여러 개 가질 수 있다.
- 적어도 한번은 전송됨(최선의 노력으로 메시지 순서 지정을 하는 이유)
-> 메세지가 소비자에 의해 빠르게 처리되지 않으면 다른 소비자가 수신한게 된다.
- 소비자가 메시지를 처리하면 메시지를 삭제해야 한다.
- SQS 대기열의 처리량을 늘려야 한다면 소비자를 추가하고 수평 확장으로 처리량을 개선
-> ASG(Auto Scaling groups)와 더불어 SQS를 사용하는 사례

(설명)
(1) 소비자가 ASG의 내부에서 EC2 인스턴스를 실행하고 SQS 대기열에서 메시지를 폴링할 것이다.
(2) ASG는 일종의 지표에 따라 확장되어야 한다.
(2-1) 지표: 대기열의 길이(ApproximateNumberOfMessages)
-> 모든 SQS 대기열에서 쓸 수 있는 CloudWatch 지표
(2-2) 알람을 설정할 수도 있다.
-> 대기열의 길이가 특정 수준을 넘어가면 CloudWatch Alarm을 설정
-> 이 알람을 통해 ASG의 용량을 늘림.
-> 그러면 더 많은 메시지가 SQS 대기열에 있을 수 있게 된다.
SQS는 애플리케이션 티어간 분리를 위해 사용한다.

- 프론트엔드가 요청을 받고 비디오가 처리되어야 할때
프론트엔드가 처리를 한 후 S3 버킷에 삽입한다.
-> 이는 처리 시간이 오래 걸릴 수 있고, 프론트에서 처리하면 웹사이트의 속도가 느려질 수 있다.
- 대신 애플리케이션을 분리
파일 처리 요청과 실제 파일 처리가 서로 다른 애플리케이션에서 발생할 수 있도록 하자
- 파일 처리 요청을 받을 떄마다 SQS 대기열로 메시지를 전송한다.
처리 요청을 할 때 해당 파일은 SQS 대기열에 있게 된다.
- 자체 오토 스케일링 그룹에 속할 백엔드 처리 애플리케이션이라는 두 번째 처리 계층을 생성
이 애플리케이션이 메시지를 수신하고 비디오를 처리하고 S3버킷에 삽입할 것이다.
- 상황에 따라 프론트엔드를 확장할 수 있고, 백엔드도 확장할 수 있다.
또한 독립적으로 확장할 수 있다.
다시말하지만 SQS 대기열은 처리량이 무제한이고, 대기열 메시지 수에 제한이 없다.
+ 생상자와 소비자(프론트와 백엔드)에서 상황에 맞는 인스턴스를 활용 가능.
SQS - 보안
- 암호화
- HTTPS API를 사용해 메시지가 생성되고 보내는 과정에서 암호화
- KMS 키를 사용해 미사용 암호화를 얻는다.
- 클라이언트 측 암호화도 가능하다
-> 클라이언트가 자체적으로 암호화 및 암호 해독을 수행(SQS가 지원하는게 아님)
- 엑세스 제어를 위해 IAM 정책은 SQS API에 대한 액세스를 규제 가능
- SQS 액세스 정책(S3 버킷 정책과 유사)
- SQS 대기열에 대한 교차 계정 액세스를 수행하거나
- SNS나 S3같은 다른 서비스가 SQS 대기열에 S3 이벤트 같은 것을 쓸 수 있게 허용하려는 경우
SQS - Message Visivility Timeout(메세지 가시성 시간 초과)

-
소비자가 메시지를 폴링하면 그 메세지는 다른 소비자에게 보이지 않게 된다.
-
소비자가 메시지받기를 요청하면 대기열에서 메시지가 반환된다.
이때 메세지 가지성 시간 초과가 시작된다.
-
기본값으로 메시지 가시성 시간 초과는 30초이다.
이는 30초안에 메시지가 처리되어야 한다는 뜻이다.
-
만약 다른 소비자가 메시지 요청 API를 호출하면 메시지가 반환되지 않는다.
즉, 가시성 시간 초과 기간 내에서는 그 메세지는 다른 소비자에게 보이지 않는다.
-
그러나 가시성 시간 초과가 경과되고 메시지가 삭제되지 않으면 메시지는 대기열에 다시 넣어진다.
그럼 다른 소비자나 동일한 소비자가 다시 요청하면 이전의 그 메시지를 또 받는다.
-
위 도표에서 가시성 시간 초과 기간내에 메시지를 처리하지 않으면 메시지가 두 번 처리될 수도 있다.
-> 두 명의 다른 소비자가 수신하거나
-> 동일한 소비자가 두 번 수신하기 때문
-
그러나 소비자가 적극적으로 메시지를 처리하고 있지만 메시지를 처리하는데 시간이 더 필요한 경우
- 메시지를 처리하지 않아 가시성 시간 초과 기간을 벗어날 때를 위해
ChangeMessageVisibility API를 사용
-> 소비자가 메시지를 처리하는데 시간이 더 필요하다는 것을 알고 있고 해당 메시지를 두 번 처리하고 싶지 않다면 위 API를 호출해 SQS에 알리면 된다.
-
메시지 가시성 시간 초과를 어떻게 설정할까?
- 기본값을 매우 높은 값으로 설정하면?
소비자가 충돌했을 때 이 메시지가 다시 나타날 때까지 오래 걸리게 된다.
- 기본값을 매우 낮은 값으로 설정하면?
메세지 처리할 시간이 부족해 메시지를 여러번 읽어 중복처리될 수 있다.
- 즉, 가시성 시간 초과는 애플리케이션에 합당한 것으로 설정되어야 한다.
메시지 처리하다가 시간이 더 필요할 것 같을 때 API를 호출하도록 프로그래밍해야 한다.
Message Visibility Timeout 실습
SQS 메시지를 만들고 Send Massage 누른다
첫 번째 사용자가 있고 두 번째 사용자가 있을때
첫 번째 사용자가 poll for messages를 눌러 메시지를 받으면
두 번째사용자가 poll for messages를 눌러도 메시지가 뜨지 않는다.
-> 메시지 가기성 시간 초과가 동작 중(30초)
첫 번째 사용자가 polling을 멈췄지만 메시지를삭제하지 않았다라고 한다면
30초 뒤에 대기열에 이전 메시지가 다시 보이게 된다.
이 때 두 번째 사용자가 메시지를 받고 작업 후 메시지를 삭제했다.
하지만 메세지는 이미 두 번 수신된 것이다.
- Visibility timeout은 0 ~ 12시간까지 설정 가능(권장 x)
- 소비자가 메세지 처리에 더 많은 시간이 필요하다면
ChangeMessageVisibility API를 호출해 메시지 가시성을 편집해 값을 늘린다.
SQS - Long Polling

- 소비자가 대기열에 메시지를 요청하는데 대기열에 아무것도 없다면?
메세지 도착을 기다리면 된다.
-> 이것이 롱 폴링
-> 롱 폴링은 1 ~ 20초로 구성이 가능하다.
- 이렇게 하는 이유?
- 지연시간을 줄이기 위해
- 즉, 빈 대기열에 소비자가 폴링을 요청하면 롱 폴링상태가 된다.
롱 폴링 중에 메시지가 도착하면 자동으로 즉시 소비자에게 전송된다.
-> 지연시간이 짧음.
- SQS로 보내는 API 호출 숫자를 줄이기 위해
애플리케이션의 효율성과 대기 시간을 증가시킨다.
- 롱 폴링 구성 방법(2가지)
- 대기열 레벨에서 구성
폴링하는 아무 소비자로부터 롱 폴링을 활성화
- WaitTimeSeconds 지정
소비자가 스스로 롱 폴링을 하도록 선택할 수 있다.
SQS - FIFO Queue

- FIFO
Standard Queue보다 순서를 보장하는 방법
- 생산자가 SQS 대기열로 메시지를 4개의 메시지를 보낸다.
SQS FIFO 대기열은 소비자가 메시지를 불러올때 생산자가 보낸 순서 그대로 메시지를 받는다.
- FIFO 대기열은 순서를 보장하기 때문에 SQS 대기열 처리량에 제한이 있다.
- 개별 메세지의 경우 초당 300개 메시지 처리
- 묶음의 메세지의 경우 초당 3,000개 메시지 처리
- 중복 제거기능
정확히 한 번만 보낼 수 있게 해준다.
- 메세지 처리도 소비자에 의해 순서대로 처리된다.
- 따라서 분리가 발생하거나 메세지의 순서를 유지할 필요가 있을때 사용하면 된다.
+ SQS로 너무 많은 메시지를 보내지 않도록 처리량에 제한도 할 수 있다.
- SQS FIFO Queue를 생성할때 이름에 .fifo를 붙여야 한다.
- SQS FIFO Queue를 구성할때 Content-based deduplication(컨텐츠 기반 중복 제거)설정이 있다.
5분 이내의 짧은 시간 동안 동일한 메시지가 두 번 발송될때 중복을 방지하는 설정이다.
SQS ASG(Auto Scaling Group) - 시험
- 분리 또는 급증하는 로드나 시간초과 문제에서 신속한 스케일링이 필요한 경우 SQS ASG를 기억하자

(ㄱ) SQS 대기열과 ASG가 있을때 ASG내에 있는 인스턴스에 메시지를 폴링한다.
이는 ASG을 자동으로 대기열 크기에 따라 확장하기 위함.
-> CloudWatch 지표인 대기열 길이를 보고 결정할 수 있다.(ApproximateNumberOfMessages)
--> 이 지표는 대기열에 몇 개의 메시지가 남아 있는지 표시한다.
(ㄴ) 지표를 통해 알람을 지정
지표가 1,000을 넘으면 지연이 발생한다 파악하고 경보를 생성해 인스턴스 수를 늘림.
(ㄷ) 이후 SQS 대기열 크기가 줄어들면 자동으로 인스턴스 축소 실행
ASG 활용 패턴 (1)

- 대대적인 세일 행가 진행중일 때
수많은 고객의 주문이 예상됨
- 이때 주문은 여러 유형의 DB에 저장될 수 있다.
RDS, Aurora(OLTP 유형), DynamoDB(NoSQL 유형)등
- 이때 트랜잭션 내역은 매우 빠른 속도로 RDS나 Aurora에 쓰일것이다.
- 애플리케이션에서 주문 요청을 처리할 것이다.
DB가 오버로드되는 등 다양한 이유로 트랜잭션에 오류가 발생하면 해당 고객 트랜잭션은 유실된다.
해결 방안

- (1) 쓰기 대상 DB에서 SQS를 버퍼로 사용
- 동일한 DB와 애플리케이션이 있을때 중간에 SQS 대기열을 생성
-> 애플리케이션이 트랜잭션을 무한히 확장 가능한 SQS 대기열에 먼저 쓰는 방식
-> 처리량 문제가 발생하지 않음
- 여기서 또 다른 ASG로 메시지를 대기열에서 제외할 수도 있다.
이 ASG는 SQS 메시지를 받아 DB로 삽입하는 작업
-> DB에 메시지가 삽입이 되면 기존 SQS 대기열에서 해당 메시지를 삭제
이 패턴은 클라이언트에세 따로 DB에 쓰였다는 확인을 전송할 필요가 없을때만 사용 가능한 방법.
ASG 활용 패턴 (2)

- DB 쓰기간 분리와 애플리케이션 티어 간 분리에 활용
(ㄱ) 애플리케이션이 요청을 전달받아 처리한 후
(ㄴ) 응답을 재전송하는 대신 이 과정을 분리해 모든 요청을 프론트엔드 웹 애플리케이션에서 받고
(ㄷ) 해당 요청을 SQS 대기열로 전송해 백엔드 처리 작업이 메시지를 전달받은 다음
(ㄹ) 준비되면 메시지를 처리하고 필요에 따라 스케일링한다.