클래식 솔루션 아키텍처

silver's avatar
Nov 17, 2025
클래식 솔루션 아키텍처

1. WhatsTheTime.com - 시간 조회 서비스

비즈니스 요구사항

  • 사용자에게 현재 시간을 보여주는 간단한 웹 서비스
  • 트래픽이 시간대에 따라 변동
  • 고가용성 필요

진화 단계

1단계: 단일 인스턴스 (초기 MVP)

Internet ↓ [Elastic IP][EC2 t3.micro] └─ 애플리케이션 서버
장점:
  • 구현이 간단
  • 저렴한 비용
문제점:
  • 단일 장애점 (SPOF)
  • 확장 불가능
  • 인스턴스 재시작 시 다운타임
월 예상 비용: ~$10

2단계: Elastic IP + 수직 확장

Internet ↓ [Elastic IP][EC2 m5.large] ← 더 큰 인스턴스
개선 사항:
  • 더 많은 트래픽 처리 가능
  • Elastic IP로 IP 고정
여전한 문제:
  • 여전히 SPOF
  • 확장 한계 존재
  • 다운타임 발생
월 예상 비용: ~$70

3단계: Multi-AZ 고가용성

Internet ↓ [Route 53] - Health Check ↓ ┌──────────────┬──────────────┐ │ AZ-A │ AZ-C │ │ [EC2 Primary][EC2 Standby]│ │ [Elastic IP][Elastic IP] │ └──────────────┴──────────────┘
개선 사항:
  • 고가용성 확보
  • 자동 장애 조치
문제점:
  • Standby 서버 유휴 상태 (비용 낭비)
  • 수동 확장 필요
월 예상 비용: ~$140

4단계: 로드 밸런서 + Auto Scaling

Internet ↓ [Route 53][Application Load Balancer][Auto Scaling Group] ├── [EC2] AZ-A ├── [EC2] AZ-A ├── [EC2] AZ-C └── [EC2] AZ-C 설정: - Min: 2 - Desired: 4 - Max: 10 - Target: CPU 50%
개선 사항:
  • 자동 확장/축소
  • 모든 인스턴스 활성 사용
  • 비용 최적화
  • Elastic IP 불필요
월 예상 비용: $80-200 (트래픽에 따라)

5단계: 예약 인스턴스로 비용 절감

[Auto Scaling Group] ├── [예약 인스턴스 2개] ← 기본 용량 (40% 할인) └── [온디맨드 0-8개] ← 확장 용량
비용 절감:
  • 기본 2개 인스턴스: 1년 예약 (40% 할인)
  • 확장 인스턴스: 온디맨드
월 예상 비용: $60-180

최종 아키텍처 (프로덕션 레벨)

Internet ↓ [Route 53] - Health Check ↓ [CloudFront] ← CDN 추가 ↓ [Application Load Balancer] ↓ HTTPS (SSL 종료) [Auto Scaling Group] ├── [EC2] AZ-A ├── [EC2] AZ-A ├── [EC2] AZ-C └── [EC2] AZ-C ↓ 캐싱 [ElastiCache Redis][RDS Multi-AZ]
최종 개선 사항:
  • CloudFront로 글로벌 성능 향상
  • ElastiCache로 DB 부하 감소
  • RDS Multi-AZ로 데이터 고가용성
  • SSL/TLS 보안 적용
월 예상 비용: $200-400

2. MyClothes.com - 쇼핑몰 서비스

비즈니스 요구사항

  • 상품 목록 조회
  • 장바구니 기능
  • 사용자 세션 관리
  • 글로벌 배송

아키텍처 설계

프론트엔드 계층

사용자 ↓ [Route 53] ↓ [CloudFront] ├── Origin: S3 (정적 콘텐츠) │ └── HTML, CSS, JS, 이미지 └── Origin: ALB (동적 콘텐츠) └── API 요청
정적 콘텐츠 전략:
  • S3에 React/Vue 빌드 파일 배포
  • CloudFront로 전 세계 배포
  • 버전 관리: v1.0.1/, v1.0.2/
동적 콘텐츠:
  • API Gateway 또는 ALB
  • Lambda 또는 EC2

애플리케이션 계층

[Application Load Balancer][Auto Scaling Group] ├── [EC2 - Spring Boot] ├── [EC2 - Spring Boot] └── [EC2 - Spring Boot] ↓ 세션 저장소: [ElastiCache Redis]
세션 관리 전략:
❌ 로컬 세션 (문제)
사용자 → ALB → EC2-1 (로그인) ✅ 사용자 → ALB → EC2-2 (세션 없음) ❌
✅ ElastiCache 세션 (해결)
EC2-1 ─┐ EC2-2 ─┤→ [Redis] ← 중앙 세션 저장소 EC2-3 ─┘ 어느 서버로 가도 세션 유지 ✅
Spring Boot 설정:
// build.gradle dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.springframework.session:spring-session-data-redis' } // application.yml spring: session: store-type: redis redis: host: elasticache-endpoint.cache.amazonaws.com port: 6379

장바구니 관리

옵션 1: Redis (추천)
// 장바구니 추가 redisTemplate.opsForList().rightPush("cart:user123", productId); // 장바구니 조회 List<String> cart = redisTemplate.opsForList().range("cart:user123", 0, -1); // 만료 시간 설정 (24시간) redisTemplate.expire("cart:user123", 24, TimeUnit.HOURS);
장점:
  • 빠른 속도 (메모리 기반)
  • TTL 자동 처리
  • 구매 전까지는 DB 부하 없음
옵션 2: DynamoDB
# 장바구니 항목 저장 table.put_item( Item={ 'userId': 'user123', 'productId': 'prod456', 'quantity': 2, 'ttl': int(time.time()) + 86400 # 24시간 } )
장점:
  • 서버리스 (관리 불필요)
  • 무제한 확장
  • TTL 자동 삭제

데이터베이스 계층

[RDS Aurora MySQL] ├── Writer Instance (쓰기) │ └── 주문, 재고 업데이트 └── Reader Instances (읽기) └── 상품 조회, 주문 내역
테이블 설계:
-- 상품 테이블 CREATE TABLE products ( product_id VARCHAR(50) PRIMARY KEY, name VARCHAR(200), description TEXT, price DECIMAL(10,2), stock INT, image_url VARCHAR(500) ); -- 주문 테이블 CREATE TABLE orders ( order_id VARCHAR(50) PRIMARY KEY, user_id VARCHAR(50), total_amount DECIMAL(10,2), status VARCHAR(20), created_at TIMESTAMP ); -- 주문 상세 테이블 CREATE TABLE order_items ( order_item_id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id VARCHAR(50), product_id VARCHAR(50), quantity INT, price DECIMAL(10,2) );
읽기/쓰기 분리:
@Service public class ProductService { @Autowired @Qualifier("writerDataSource") private JdbcTemplate writerTemplate; @Autowired @Qualifier("readerDataSource") private JdbcTemplate readerTemplate; // 읽기: Reader 사용 public List<Product> getProducts() { return readerTemplate.query("SELECT * FROM products", ...); } // 쓰기: Writer 사용 public void updateStock(String productId, int quantity) { writerTemplate.update( "UPDATE products SET stock = stock - ? WHERE product_id = ?", quantity, productId ); } }

이미지 저장소

[S3 Bucket - Product Images] ├── products/ │ ├── prod001.jpg │ ├── prod002.jpg │ └── ... └── thumbnails/ ├── prod001_thumb.jpg └── prod002_thumb.jpg [CloudFront] ← CDN └── https://d1234567.cloudfront.net/products/prod001.jpg
S3 이벤트 트리거로 썸네일 자동 생성:
S3 Upload (원본 이미지) ↓ S3 Event [Lambda Function] ├── 이미지 리사이징 (Sharp/Pillow) └── 썸네일 S3 저장

전체 아키텍처

┌─────────────────────────────────────────┐ │ CloudFront (CDN) │ ├────────────────┬────────────────────────┤ │ Origin: S3 │ Origin: ALB │ │ (정적 파일) │ (API) │ └────────────────┴────────────────────────┘ ↓ ┌─────────────────────────┐ │ Application Load Balancer│ └─────────────────────────┘ ↓ ┌─────────────────────────┐ │ Auto Scaling Group │ │ ├─ EC2 (Spring Boot) │ │ ├─ EC2 (Spring Boot) │ │ └─ EC2 (Spring Boot) │ └─────────────────────────┘ ↓ ↓ ┌────────┴────┐ ┌────────────┐ │ ElastiCache │ │ RDS Aurora │ │ Redis │ │ MySQL │ │ (세션/캐시) │ │ (주문/상품) │ └─────────────┘ └────────────┘ ↓ ┌──────────────┐ │ S3 (이미지) │ └──────────────┘

3. MyWordPress.com - 블로그 플랫폼

비즈니스 요구사항

  • WordPress 멀티 사이트
  • 빠른 이미지 로딩
  • 확장 가능한 아키텍처

아키텍처 설계

Internet ↓ [Route 53][Application Load Balancer][Auto Scaling Group] ├── [EC2 - WordPress] AZ-A └── [EC2 - WordPress] AZ-C ↓ ↓ [EFS] [Aurora MySQL] (공유 파일) (데이터베이스)

핵심 포인트

1. EFS로 파일 공유

문제:
사용자 → EC2-1 (업로드 image.jpg) ✅ 사용자 → EC2-2 (image.jpg 없음) ❌
해결: EFS 마운트
# 모든 EC2 인스턴스에서 EFS 마운트 sudo mount -t efs fs-12345678:/ /var/www/html/wp-content/uploads # /etc/fstab에 추가 (자동 마운트) fs-12345678:/ /var/www/html/wp-content/uploads efs defaults,_netdev 0 0
이제 모든 인스턴스가 동일한 파일 공유:
EC2-1 ─┐ EC2-2 ─┤→ [EFS: /wp-content/uploads] EC2-3 ─┘

2. Aurora MySQL

wp-config.php 설정:
// Writer Endpoint (쓰기) define('DB_HOST', 'mywordpress-cluster.cluster-xxxxx.ap-northeast-2.rds.amazonaws.com'); // Reader Endpoint (읽기) - 선택적 define('DB_HOST_READER', 'mywordpress-cluster.cluster-ro-xxxxx.ap-northeast-2.rds.amazonaws.com');

3. CloudFront 추가 (선택)

[CloudFront] ├── Origin: ALB (동적 콘텐츠) │ └── PHP 페이지 └── Behavior: /wp-content/uploads/* └── Origin: S3 또는 EFS (이미지)
개선 사항:
  • 이미지 로딩 속도 향상
  • 글로벌 배포
  • ALB 부하 감소

성능 최적화

1. Redis 캐시 추가

[WordPress][Redis][Aurora] ↑ 캐시 플러그인 (W3 Total Cache, Redis Object Cache)
플러그인 설정:
// wp-config.php define('WP_REDIS_HOST', 'redis-endpoint.cache.amazonaws.com'); define('WP_REDIS_PORT', 6379); define('WP_CACHE', true);

2. CDN 구성

정적 파일: - CSS, JS CloudFront - 이미지 → CloudFront (EFS Origin) - 동적 페이지 → ALB

4. 애플리케이션을 빠르게 인스턴스화하기

문제: User Data 스크립트가 느림

#!/bin/bash yum update -y # 5분 yum install -y httpd # 2분 systemctl start httpd # 30초 # 총 7분 30초 소요
Auto Scaling 시:
  • 트래픽 증가 감지: 1분
  • 인스턴스 시작: 1분
  • User Data 실행: 7분 30초
  • 헬스 체크 통과: 1분
  • 총 10분 30초 ← 너무 느림!

해결책

방법 1: Golden AMI

개념:
  • 애플리케이션이 미리 설치된 AMI 생성
  • 부팅 즉시 서비스 시작
생성 과정:
# 1. 기본 인스턴스 생성 # 2. 소프트웨어 설치 및 설정 yum install -y httpd php mysql # 애플리케이션 배포 # 설정 파일 구성 # 3. AMI 생성 aws ec2 create-image \ --instance-id i-1234567890abcdef0 \ --name "MyApp-Golden-v1.0.0"
효과:
  • User Data 실행: 7분 30초 → 30초
  • 총 시작 시간: 10분 30초 → 3분
단점:
  • AMI 업데이트 필요 (버전 관리)
  • 빌드 파이프라인 복잡도 증가

방법 2: User Data + EFS

User Data를 최소화:
#!/bin/bash # EFS 마운트만 수행 mount -t efs fs-12345678:/ /var/app # 애플리케이션은 EFS에 미리 배포됨 systemctl start myapp
효과:
  • User Data: 30초 이내
  • 배포 업데이트: EFS만 수정하면 됨

방법 3: Hybrid (Golden AMI + User Data)

Golden AMI:
  • OS 패키지
  • 런타임 환경
  • 기본 설정
User Data:
  • 환경별 설정 (dev/prod)
  • 최신 애플리케이션 코드 다운로드
  • 동적 설정 적용
#!/bin/bash # S3에서 최신 코드 다운로드 aws s3 cp s3://my-deployments/app-v1.2.3.jar /opt/app/ # 환경 변수 설정 export DB_HOST=${DB_ENDPOINT} export REDIS_HOST=${REDIS_ENDPOINT} # 애플리케이션 시작 systemctl start myapp
효과:
  • 빠른 시작: 2-3분
  • 유연한 배포
  • AMI 재생성 빈도 감소

5. Elastic Beanstalk 개요

개념

Elastic Beanstalk는 AWS의 PaaS(Platform as a Service)로, 인프라를 자동으로 관리
개발자가 하는 것: - 코드 작성 - ZIP 파일 업로드 Beanstalk가 하는 것: - EC2 인스턴스 생성 - Auto Scaling 구성 - Load Balancer 설정 - 모니터링 설정 - 배포 자동화

Beanstalk 아키텍처

[Elastic Beanstalk] ├── [Application Load Balancer] │ └── [Auto Scaling Group] │ ├── [EC2] - Your App │ ├── [EC2] - Your App │ └── [EC2] - Your App ├── [RDS] (선택적) ├── [ElastiCache] (선택적) └── [CloudWatch] (모니터링)

지원 플랫폼

  • Java: Spring Boot, Tomcat
  • Node.js: Express, Nest.js
  • Python: Django, Flask
  • Ruby: Rails, Sinatra
  • .NET: ASP.NET Core
  • PHP: Laravel, Symfony
  • Go: Gin, Echo
  • Docker: 커스텀 컨테이너

사용 예시

CLI로 배포

# EB CLI 설치 pip install awsebcli # 초기화 eb init -p python-3.9 my-app --region ap-northeast-2 # 환경 생성 및 배포 eb create prod-env # 코드 업데이트 git commit -am "Update feature" eb deploy # 환경 상태 확인 eb status eb health # 로그 확인 eb logs # SSH 접속 eb ssh # 환경 삭제 eb terminate prod-env

배포 전략

1. All at once (전체 동시)
모든 인스턴스 동시 업데이트 → 다운타임 발생 (짧음) → 빠른 배포 → 개발 환경에 적합
2. Rolling (순차)
배치 단위로 순차 업데이트 배치 1: [Old] [Old][New] [New] 배치 2: [Old] [Old][New] [New] → 다운타임 없음 → 배포 중 용량 감소
3. Rolling with additional batch
추가 인스턴스 생성 후 순차 업데이트 [Old] [Old] [Old] [Old] + [New] [New][New] [New] [New] [New] → 다운타임 없음 → 전체 용량 유지 → 추가 비용 발생 (일시적)
4. Immutable (불변)
완전히 새로운 Auto Scaling Group 생성 Old ASG: [Old] [Old] [Old] New ASG: [New] [New] [New] ← 테스트 → 성공 시 Old ASG 제거 → 가장 안전 → 빠른 롤백 → 비용 높음 (2배)
5. Blue/Green
새 환경 완전 생성 Blue (구버전): www.example.com Green (신버전): www-staging.example.com 테스트 완료 후 DNS 스왑: www.example.com → Green www-staging.example.com → Blue → 즉시 롤백 가능 → 제로 다운타임 → 비용 가장 높음

비용 비교

직접 관리 vs Beanstalk

직접 관리 (DIY):
EC2: $70 ALB: $20 운영 시간: 20시간/월 × $50/시간 = $1,000 ───────────── 총: $1,090/월
Elastic Beanstalk:
EC2: $70 ALB: $20 Beanstalk: $0 (무료!) 운영 시간: 2시간/월 × $50/시간 = $100 ───────────── 총: $190/월 (82% 절감)

💡
  • 단순하게 시작하여 점진적으로 개선
  • Auto Scaling + ALB로 확장성 확보
  • ElastiCache로 세션 및 캐시 관리
  • EFS로 파일 공유 (WordPress 등)
  • Golden AMI로 빠른 시작
  • Elastic Beanstalk로 운영 부담 감소
Share article

silver