Video coming soon
Please continue with the lesson material below.
지도 한 장 — 이커머스 쇼핑몰
Log in to save your progressLesson Material
지도 한 장 — 이커머스 쇼핑몰
앞에서 이름과 용도를 외운 서비스들이 실제로 어디에 놓이는지 한 장에 모았습니다. 이 그림이 덮는 범위가 전체 출제의 4분의 1(24.1%)입니다. 외우려 하지 말고 눈에 익히세요.

가정한 서비스
중견 규모 온라인 쇼핑몰입니다. 요구사항을 이렇게 잡았습니다.
- 상품 이미지가 많고 전 세계에서 접속한다
- 평소 트래픽은 완만하지만 세일 시작 순간 10배로 뛴다
- 주문이 들어오면 재고 차감, 알림 발송, 분석 적재가 각각 일어나야 한다
- 장바구니는 세션이 끊겨도 유지돼야 한다
- AZ 하나가 죽어도 서비스가 멈추면 안 된다
이 다섯 줄이 그대로 설계 결정으로 이어집니다.
전체 흐름
이용자 → Route 53 → CloudFront (+ WAF)
├─ 정적(이미지·JS·CSS) → S3 (OAC로 비공개)
└─ 동적 → IGW → ALB → ECS Fargate
├→ ElastiCache Redis (세션 저장소)
├→ RDS Proxy → Aurora Writer/Reader
│ └ 클러스터 볼륨 (3 AZ 6중 복제)
├→ Gateway Endpoint → DynamoDB (장바구니)
└→ SNS 주문 토픽
├→ SQS 재고 → Lambda (실패 시 DLQ)
├→ SQS 알림 → Lambda
└→ SQS 분석 → EventBridge Pipes → Firehose → S3
계층별 설계 근거
진입 계층 — Route 53 / CloudFront / WAF
정적 자산을 EC2나 ALB가 서빙하면 트래픽이 늘수록 서버가 같이 늘어야 합니다. CloudFront를 앞에 두면 이미지·JS·CSS가 엣지에서 끝나므로 뒤쪽 용량 계획에서 정적 트래픽이 통째로 빠집니다.
S3 버킷은 퍼블릭으로 열지 않고 OAC로 CloudFront만 접근하게 하고, Block Public Access를 켭니다.
WAF는 CloudFront에 붙였습니다. ALB에 붙여도 되지만 CloudFront에 붙이면 엣지에서 걸러 리전까지 오지 않습니다.
WAF 우회 차단이 필요합니다. CloudFront 앞에 WAF를 두어도 공격자가 ALB의 DNS 이름을 직접 때리면 WAF를 건너뜁니다. 그래서 ALB 보안 그룹의 인바운드를 CloudFront 관리형 prefix list(
com.amazonaws.global.cloudfront.origin-facing) 로만 제한하고, CloudFront가 붙이는 커스텀 헤더를 ALB 리스너 규칙에서 검증합니다. 다이어그램의 빨간 메모가 이 내용입니다.
애플리케이션 계층 — ALB + ECS Fargate
ALB는 VPC에 귀속된 리소스 하나이고, 각 AZ의 퍼블릭 서브넷에는 그 ALB의 노드와 ENI가 배치됩니다. ELB 문서가 "활성화한 각 가용 영역에 로드 밸런서 노드를 만들고, 해당 서브넷에 네트워크 인터페이스를 만든다"고 명시합니다. 다이어그램에서 ALB 아이콘을 하나만 두고 서브넷에는 ALB ENI를 그린 이유입니다. ALB를 AZ마다 하나씩 그리면 로드밸런서가 2대인 것처럼 읽힙니다.
컨테이너를 고른 이유는 배포 단위를 고정하고 스케일 아웃을 빠르게 하기 위해서입니다. EC2 시작 유형 대신 Fargate를 쓴 건 호스트 OS 패치 책임을 없애기 위함이고, "세일 시작 10배"에 대응하는 것은 ECS Service Auto Scaling입니다(ALB 요청 수 또는 CPU 기준 target tracking).
앱 서브넷은 프라이빗이고, 외부 결제 API 호출 같은 아웃바운드는 NAT Gateway를 거칩니다. NAT는 AZ마다 하나씩 둡니다. 하나만 두면 그 AZ가 죽을 때 반대편 AZ의 아웃바운드가 같이 끊깁니다.
엔드포인트 — 두 종류를 구분해서 그렸습니다
| 종류 | 대상 | 실체 | 다이어그램 위치 |
|---|---|---|---|
| Gateway Endpoint | S3, DynamoDB | 라우팅 테이블 항목. ENI도 보안 그룹도 없음 | VPC 레벨 (서브넷 밖) |
| Interface Endpoint | ECR, CloudWatch Logs, Secrets Manager | 서브넷 안의 ENI. 보안 그룹 적용됨 | 앱 서브넷 안 |
이 구분이 중요합니다. 프라이빗 서브넷의 Fargate는 이미지를 ECR에서 풀하고 로그를 CloudWatch로 보냅니다. 인터페이스 엔드포인트가 없으면 이 트래픽이 전부 NAT Gateway를 거쳐 데이터 처리 요금이 붙습니다. 게이트웨이 엔드포인트만 두고 "NAT 비용을 없앴다"고 하면 절반만 맞는 말입니다.
캐시 계층 — ElastiCache Redis
세션 저장소입니다. 세션이 인스턴스 안에 있으면 태스크가 교체될 때마다 로그인이 풀리고, 그러면 오토스케일링이 무의미해집니다. 상품 조회 캐싱도 겸해 DB에 도달하는 읽기 총량을 줄입니다.
Memcached가 아니라 Redis인 이유는 복제와 자동 페일오버가 필요하기 때문입니다. AZ-a에 Primary, AZ-b에 Replica를 두고 Multi-AZ 자동 페일오버를 켭니다.
장바구니 데이터 자체는 DynamoDB에 영속 저장합니다. 세션(Redis)과 장바구니(DynamoDB)는 다른 저장소입니다.
데이터 계층 — RDS Proxy + Aurora
Aurora에는 standby가 없고, 인스턴스끼리 복제하지도 않습니다. RDS Multi-AZ와 혼동하기 쉬운 지점입니다.
Aurora는 컴퓨팅(인스턴스)과 스토리지가 분리된 구조입니다. Writer와 Reader는 각자 DB 서브넷에 있지만, 데이터는 서브넷 밖 서비스 관리 영역의 클러스터 볼륨 하나에 있고 그 볼륨이 3개 AZ에 6중 복제됩니다. 그래서 다이어그램에서도 Writer와 Reader를 직접 잇지 않고 둘 다 클러스터 볼륨에 연결했습니다. Writer가 볼륨에 쓰고 Reader가 같은 볼륨을 읽습니다.
장애 시에는 Reader 중 하나가 Writer로 승격됩니다. 데이터 복사가 일어나지 않으므로 승격이 빠릅니다. 즉 Reader는 읽기 확장과 페일오버 대상을 겸합니다.
RDS Proxy는 서로 다른 AZ의 서브넷 2개 이상을 요구합니다. AZ-a에만 두면 요건 위반이자 단일 장애점이 되므로 양쪽 AZ에 ENI를 둡니다.
DB 자격증명은 Secrets Manager에 두고 자동 교체합니다. 태스크는 IAM role로 읽으므로 어디에도 비밀번호가 적히지 않습니다.
비동기 계층 — SNS + SQS + Lambda
주문 하나에 재고·알림·분석이 각각 반응해야 합니다. SQS 하나만 쓰면 메시지를 한 소비자만 가져가므로 성립하지 않습니다. SNS로 1:N 발행하고, 각 구독자 앞에 SQS를 둬서 소비자가 죽어도 메시지가 보존되게 했습니다.
세일 시작 순간의 폭주는 큐가 흡수합니다. 주문 API는 큐에 넣고 바로 응답하므로 뒷단 처리 속도와 분리됩니다.
재고 차감이 반복 실패하면 DLQ로 격리해 나머지 메시지 처리를 막지 않게 합니다.
SQS는 Firehose의 직접 소스가 아닙니다. Firehose가 받을 수 있는 소스는 Direct PUT, Kinesis Data Streams, CloudWatch Logs/Events, IoT입니다. 분석 큐를 Firehose로 흘리려면 EventBridge Pipes(SQS 소스 → Firehose 타깃)를 사이에 둬야 합니다. 다이어그램이 그렇게 되어 있습니다.
사용된 패턴 24개
| 배지 | 패턴 | 이 아키텍처의 어디 | 왜 여기에 |
|---|---|---|---|
| P 1.1 | 단일 서버 웹앱을 고가용 3계층으로 | AZ-a/b 전체 구조 | AZ 장애에도 서비스 지속 |
| P 1.2 | 세션 외부화로 웹 계층 무상태화 | ECS → Redis | 태스크 교체·오토스케일링의 전제 |
| P 1.3 | 정적 콘텐츠 오프로드 | CloudFront → S3 | 앱 계층에서 정적 트래픽 제거 |
| P 2.1 | 읽기 부하 분산 + 캐싱 계층 | Redis + Aurora Reader | 읽기 총량 감소 후 남은 것만 분산 |
| P 2.2 | 컨테이너 + RDS Proxy | ECS → RDS Proxy → Aurora | 태스크 급증 시 커넥션 고갈 방지 |
| P 3.1 | SNS + SQS 팬아웃 | SNS 주문 토픽 → SQS 3개 | 한 주문에 여러 시스템이 각자 반응 |
| P 3.2 | 큐 버퍼링 + 워커 확장 | SQS → Lambda | 세일 시작 폭주 흡수 |
| P 3.6 | DLQ로 실패 격리 | SQS 재고 → DLQ | 독성 메시지가 큐를 막지 않게 |
| P 6.1 | 퍼블릭/프라이빗 2계층 VPC | 서브넷 4티어 + AZ별 NAT | 최소 노출, AZ 독립성 |
| P 6.2 | gateway endpoint 사설 접근 | Gateway Endpoint → S3·DynamoDB | NAT 비용 제거 + 인터넷 미경유 |
| P 6.3 | interface endpoint 사설 접근 | ENI → ECR·Logs·Secrets Manager | 이미지 풀·로그 전송도 NAT 우회 |
| P 7.1 | 정적 콘텐츠 글로벌 배포 | CloudFront + S3 | 전 세계 지연 감소 |
| P 7.3 | CloudFront 오리진 보호 | OAC + Block Public Access | 버킷 직접 접근 차단 |
| P 8.2 | DB 자격증명 자동 교체 | Secrets Manager | 코드에 비밀번호 없음 |
| P 8.5 | 웹 공격·DDoS 다층 방어 | CloudFront + WAF + prefix list | 엣지에서 차단, ALB 직접 호출 봉쇄 |
| P 9.1 | 단일 장애점 제거 기본형 | 모든 계층 2 AZ 배치 | 가용성 기준선 |
| P 1.7 | 컨테이너 웹앱: ALB + ECS on Fargate | ALB → ECS on Fargate | 서버 관리 없이 컨테이너 |
| P 7.6 | CloudFront → 퍼블릭 ALB → 프라이빗 앱 | 3계층 배치 | 앱을 직접 노출하지 않음 |
| P 7.7 | 엣지 보안 스택 (CloudFront + WAF) | CloudFront + WAF | 엣지에서 먼저 거른다 |
| P 2.9 | DB 백업의 장기 보존 | AWS Backup | 35일 한도를 넘는 보존 |
| P 6.7 | 계층 간 접근 제어 (보안 그룹 체이닝) | 웹 SG → 앱 SG → 캐시/DB SG | 출처를 SG ID 로 지정 |
| P 8.7 | 전송 중 암호화와 인증서 수명주기 | ACM 두 개 (us-east-1 / 리전) | CloudFront 는 us-east-1 만 읽음 |
| P 10.3 | 지표 임계값 알림과 자동 조치 파이프라인 | CloudWatch 경보 → SNS · 스케일 아웃 | 확장의 근거가 되는 지표 |
| P 10.4 | 로그 장기 보관과 간헐적 SQL 분석 | CloudWatch Logs (앱 로그 · Flow Logs) | 막힌 트래픽 추적 |
이 아키텍처로 풀리는 시험 문제 유형
- "단일 EC2로 운영 중인데 가용성을 높여라" → P 1.1 + P 9.1
- "새로고침할 때마다 장바구니가 사라진다" → P 1.2 (세션 외부화)
- "주문 하나로 여러 시스템이 처리돼야 한다" → P 3.1 (SNS+SQS 팬아웃)
- "트래픽 급증에도 요청이 유실되면 안 된다" → P 3.2 (큐 버퍼링)
- "EC2가 인터넷 없이 S3에 접근" → P 6.2 (gateway endpoint)
- "DB 비밀번호를 주기적으로 교체" → P 8.2 (Secrets Manager)
바꿔 말하면 틀리는 지점
- Redis 대신 Memcached를 쓰면 복제·자동 페일오버가 없어 세션이 날아갑니다
- Aurora Reader를 "standby"라고 부르면 틀립니다. standby는 RDS Multi-AZ 용어이고, RDS standby는 읽기 트래픽을 받지 않지만 Aurora Reader는 받습니다
- Aurora Writer가 Reader로 데이터를 복제한다는 서술도 틀립니다. 둘은 같은 클러스터 볼륨을 보며, 복제는 스토리지 계층에서 일어납니다
- SNS 없이 SQS 하나로 팬아웃하려 하면 한 소비자만 메시지를 가져갑니다
- WAF를 NLB에 붙이는 선택지는 성립하지 않습니다
- gateway endpoint에 보안 그룹을 붙인다는 서술은 불가능합니다 (ENI가 없음). 보안 그룹이 붙는 것은 interface endpoint입니다
- SQS를 Firehose의 소스로 직접 연결하는 구성은 존재하지 않습니다
다이어그램에 그리지 않은 것 (지면 관계상 생략, 실제로는 필요)
- 라우팅 테이블: 퍼블릭 서브넷은 0.0.0.0/0 → IGW, 프라이빗은 0.0.0.0/0 → 해당 AZ의 NAT, S3·DynamoDB는 gateway endpoint prefix list
- 암호화: Aurora·DynamoDB·S3·ElastiCache 모두 KMS 고객 관리 키로 저장 시 암호화, 전 구간 TLS
- 백업: Aurora 자동 백업(최대 35일) + AWS Backup으로 장기 보존, DynamoDB PITR
- 로깅: CloudTrail(조직 추적), VPC Flow Logs, ALB·CloudFront 액세스 로그 → S3
- NAT·라우팅 연결선: 선이 교차해 가독성을 해쳐 생략했습니다. NAT의 역할은 아이콘 라벨에 적어 두었습니다
- Lambda 재고차감의 Aurora 접근선: 이 Lambda는 VPC에 연결되어 앱 서브넷에 ENI를 만들고 Aurora에 접근합니다. 선을 그리면 다이어그램을 가로질러 가독성을 해쳐 라벨로만 표기했습니다
- S3 버킷 개수: 정적 자산 버킷(CloudFront 오리진 겸 앱 업로드 대상)과 분석용 데이터 레이크 버킷 둘만 그렸습니다. 게이트웨이 엔드포인트는 전자에, Firehose는 후자에 연결됩니다
Q&A0
Only students taking this course can post questions.
No questions yet. Be the first to ask!