Repository navigation
Home
H4R4n9 edited this page Oct 15, 2026
·
13 revisions
모여타(판교 출퇴근 택시·동행 매칭 서비스) 의 클라우드 인프라 설계 기록입니다. 서비스·팀 가정에서 출발해 V1(EC2 + Docker Compose) 구축, CI/CD, SLI/SLO 정의, 부하 측정으로 찾은 V1의 한계, V2(ECS 기반 확장) 설계까지 작업 순서대로 정리했습니다.
각 문서 제목을 누르면 해당 문서로 이동합니다. 문서를 읽다가 다른 문서로 넘어갈 때는 오른쪽 사이드바나 이 페이지의 목차를 사용하세요.
| # | 작업 분류 | 진행 단계 | 문서 수 |
|---|---|---|---|
| 0 | 서비스와 팀 운영 가정 | 1단계 | 4 |
| 1 | V1 인프라 설계와 컨테이너 환경 구축 | 1단계 | 7 |
| 2 | CI 파이프라인 설계 | 2단계 | 1 |
| 3 | CD 파이프라인 설계 | 3단계 | 1 |
| 4 | 신뢰성 지표 정의 CUJ와 SLI SLO | 1단계 | 2 |
| 5 | V2 확장 가정과 V1 부하 측정 | 4단계 | 11 |
| 6 | V2 인프라 설계 | 4단계 | 7 |
| 7 | V2 모니터링과 장애 알림 | 5단계 | 2 |
flowchart LR
A["0. 서비스와 팀 가정<br/>DAU·RPS·예산"] --> B["1. V1 인프라<br/>EC2 + Compose"]
B --> C["2. CI"]
C --> D["3. CD"]
A --> E["4. CUJ · SLI/SLO"]
E --> F["5. V2 확장 가정<br/>V1 부하 측정"]
D --> F
F --> G["6. V2 인프라<br/>CloudFront·ALB·ECS·RDS·Redis"]
G --> H["7. 모니터링·장애 알림<br/>PLG + Alloy · Discord"]
- 서비스 문제와 제공 가치 가정 → 사용자 상황과 행동 기반 RPS 가정: 서비스가 무엇이고 트래픽이 얼마인지
- V1 아키텍처 설계: V1이 왜 단일 EC2 + Docker Compose인지
- V1 핵심 사용자 여정별 SLI/SLO 정의: 무엇을 기준으로 품질을 판단하는지
- V2 서비스 확장 가정 및 V1의 한계 지점: 부하 측정으로 무엇이 먼저 무너졌는지
- V2 백엔드 애플리케이션 인프라 설계: 그래서 V2를 어떻게 바꾸는지
인프라 결정의 출발점이 되는 팀 규모·예산·시장·트래픽 가정입니다. 이후 모든 문서의 수치 근거가 여기서 나옵니다.
| 문서 | 요약 | 핵심 수치·결정 |
|---|---|---|
| 팀 운영 구조와 실행 제약 가정 | 6인 스타트업의 역할 분담, V1~V3 일정, 배포 빈도, V1에서 감당 가능한 운영 복잡도를 정의 | 인프라 1명 · 예산 3개월 90만 원 · Prod 주 1회 / Dev 수시 배포 |
| 서비스 문제와 제공 가치 가정 | 출퇴근·심야 이동 사용자의 문제, 페르소나, 모집자/참여자 역할, V1에서 검증할 핵심 가치와 기능 범위 | 탐색 → 참여 → 채팅 → 정산을 하나의 흐름으로 |
| 초기 타깃 시장과 시장 검증 가정 | 판교 테크노밸리를 초기 지역으로 정한 이유, TAM·SAM·SOM 산정, MAU·DAU 정의와 시나리오 | TAM 83,465명 · SAM 약 54,169명 · 초기 도달 약 8,315명 |
| 사용자 상황과 행동 기반 RPS 가정 | 사용자 상황·플로우·예외 플로우를 정리하고 행동을 조회/쓰기/실시간 트래픽으로 나눠 초기 RPS를 산출 | 피크 조회 약 1.25 RPS · 매칭·정산 약 0.075 RPS |
비용과 운영 인력 제약 아래에서 V1을 EC2 1대 + Docker Compose 로 빠르게 띄우기 위한 설계와 구축 기록입니다.
| 문서 | 요약 | 핵심 수치·결정 |
|---|---|---|
| 서버 구성 | Nginx 단일 진입점, EC2 1대 안에서 애플리케이션을 컨테이너로 분리, Dev/Prod 인스턴스 분리, DB 컨테이너 분리를 결정 | Nginx → Next.js / Spring Boot / FastAPI |
| Docker Compose 운영 | 인스턴스 스펙 선정, 컨테이너별 CPU·메모리 제한, 도커 네트워크 분리, 의존성·재시작·실행 순서, 이미지 태그 방식 | Dev t3.medium · Prod t3.medium + swap · 앱/DB 네트워크 분리 |
| V1 아키텍처 설계 | Public Subnet 선택(NAT 비용 회피), Dev/Prod 보안 그룹, IAM, CloudWatch 로그, S3 백업, Nginx 라우팅 구조 | NAT 월 약 $86 절감 · Prod는 SSM 접속 |
| 초기 컨테이너 환경 구축 | 마일스톤별 실제 구축 기록: M1 Dockerfile(멀티 스테이지), M2 AWS 리소스·Compose 실행 환경과 브랜치·태그 정책, M3 CI/CD(GitHub Actions → ECR → EC2) | OIDC 연동 · Discord Webhook 실패 알림 |
| Docker Compose 기반 배포 마일스톤 | V1의 이미지, Compose 실행 환경, CI/CD를 M1~M3 마일스톤으로 나눠 단계별 완료 조건과 산출물을 정의 | M1 Dockerfile · M2 Compose·Nginx · M3 ECR publish·SSM deploy·rollback |
| V1 아키텍처 IaC 입력 명세 | V1 아키텍처 결정을 Terraform 리소스·변수·IAM 권한·미결정 값으로 나눈 입력 명세 | 값 상태를 확정 / 초기 권장 / 결정 필요로 구분 |
| MySQL SSM 접근 구성 스프린트 백로그 | 백엔드 개발자가 DB 포트를 공개하지 않고 개인 IAM User와 SSM 포트포워딩으로 Dev MySQL에 접속하는 구성 | 루프백 3306 바인딩 · moyeota_dev_rw 역할(DML·DDL) |
| 문서 | 요약 | 핵심 수치·결정 |
|---|---|---|
| CI 파이프라인 설계 | FE·BE·AI 독립 레포의 PR 기반 CI, 변경 영향도에 따른 트리거, 브랜치(fix/hotfix) 정책, 실패 처리, 이미지 레지스트리와 태그·수명주기 정책, Build → Test → Image Build → Push 단계 | 빌드 10분 이내 · ECR Private + 커밋 SHA Immutable 태그 + SemVer 릴리즈 태그 + Lifecycle Policy |
| 문서 | 요약 | 핵심 수치·결정 |
|---|---|---|
| CD 파이프라인 설계 | Dev/Prod CD 파이프라인 분리, 배포 전략 비교, 배포 전 검증·컨테이너 기동·Health Check·Readiness·Smoke Test 게이트, 배포 실패 처리, 단일 EC2 구조의 한계 | Dev·Prod 모두 Recreate 배포 · 검증된 동일 이미지만 Prod로 승격 |
"서비스가 느리다"를 숫자로 말하기 위해, 핵심 사용자 여정(CUJ)을 정하고 여정별 SLI/SLO를 정의했습니다. 5·6단계 부하 측정과 V2 목표의 판정 기준이 됩니다.
| 문서 | 요약 | 핵심 수치·결정 |
|---|---|---|
| V1 핵심 사용자 여정(CUJ) 정의 | SLI → SLO → SLA 관계를 정리하고, Core/Signature/Delight 경험으로 나눠 V1의 핵심 사용자 여정을 도출 | 참여자: 탐색 → 상세 → 참여 → 채팅 / 모집자: 경로 입력 → 등록 → 수락 → 채팅 |
| V1 핵심 사용자 여정별 SLI/SLO 정의 | 동행모집 참여자·모집자, 택시팟 매칭 3개 CUJ의 API 경로, 측정 위치, Good/Bad event 기준과 V1 초기 SLO | 가용성 99.9%(28일 약 40분) · 조회 p95 ≤ 1초 · 쓰기 p95 ≤ 1.5초 · 정합성 100% |
V2 성장 목표를 세우고, V1 구조에 부하를 걸어 어디가 먼저 포화되는지 실측한 문서들입니다. 6단계 V2 설계의 근거입니다.
| 문서 | 요약 | 핵심 수치·결정 |
|---|---|---|
| V2 서비스 확장 가정 및 V1의 한계 지점 | V2 기능(혼잡도·정산 AI)과 6개 업무지구 확장 가정, V2 운영 SLO와 검증 시나리오, V1 부하 측정 결과(Nginx OOM, HikariCP 대기열 포화, 좌석·택시팟 경합) | DAU 24배 · 피크 91 RPS · 행사 중첩 225.5 RPS · WebSocket 1,800 연결 |
| V1 사용자 여정 기반 부하테스트 시나리오 설계 | S1 조회 증가, S2·S3 WebSocket 연결·채팅 저장, S4 인기 팟 좌석 경합, S5 혼합·행사 스파이크 시나리오와 SLI 판정·원인 분석 지표 | k6 시나리오 · CUJ 3종 분당 12회씩 시작 |
| V1 Socket 서버 부하 측정 | WebSocket 연결 수립·유지와 STOMP 메시지 저장·전달 경로 실측. 1차 한계는 메시지 저장이 아닌 연결 수립 구간에서 발생 | 목표 36 msg/s 중 8.66 msg/s · 연결 실패 후 OOM Kill · V2 시작 스펙 0.5 vCPU / 1 GiB × 3대 |
| V1 Docker Compose 구조의 한계 분석 | V1의 현재 구조와 부하 측정으로 확인한 한계, V2 성장 시 드러나는 구조적 한계를 정리해 V2 인프라 요구사항을 도출 | t3.medium 1대에 CPU 2.00 전량 배분 · REST·WebSocket이 한 JVM · HikariCP 10 |
5단계에서 찾은 한계 지점별로 V2 구조를 결정한 문서입니다.
| 문서 | 요약 | 최종 결정 |
|---|---|---|
| V2 Nginx 인프라 설계 | 0.15 vCPU·64 MiB Nginx 하나에 모든 연결 비용이 몰리고 호스트 단위로 장애가 전파되는 한계를 분석, 진입점 대안 비교 | CloudFront → ALB(ACM) → ECS, Nginx 제거 |
| V2 DB 인프라 설계 | MySQL 조회·채팅 저장·인기 팟 경합 실측. 병목은 DB CPU가 아닌 커넥션 점유와 hot-row 경합 → 단일 writer OLTP로 판단 | RDS for MySQL Single-AZ (db.t4g.small) |
| V2 백엔드 애플리케이션 인프라 설계 | REST·WebSocket이 한 JVM을 공유해 꼬리 지연이 전파되는 문제로 두 서비스를 분리, 실행 환경·비용·task 스펙 산정 | ECS on EC2 + Spot · REST t3.small × 2, WebSocket t3.small × 3 |
| V2 WebSocket 메시지 버스와 Redis 도입 설계 | 서비스 분리 후 Simple Broker로는 인스턴스 간 전달이 안 되는 문제, Redis 용도·이벤트 계약·전달 보장과 장애 처리 | Redis Pub/Sub 를 fan-out 경로로 도입, 원본은 MySQL |
| V2 ECS 기반 전체 아키텍처 설계 | V1 Compose를 스테이지별 ECS on EC2 다중 클러스터로 전환. Prod·Non-Prod ALB, 서비스별 ASG(Capacity Provider), Redis Pub/Sub, RDS | dev·stg·prod 클러스터 × rest·websocket·frontend·fastapi 서비스 · 기준 용량 On-Demand + REST Spot |
| ECS Task Auto Scaling 정책 (작성 중) | 출퇴근 시간대 트래픽 편차에 맞춘 ASG·ECS Service Auto Scaling 정책 | 평시 3.9 RPS ↔ 출퇴근 평균 45.5 RPS(11.7배) · 순간 피크 91 RPS |
| V2 DB 무중단 마이그레이션 설계 | V1 MySQL 컨테이너 데이터를 RDS로 옮기는 방식 비교, 실행 절차, stg 리허설 측정 항목 | 읽기 전용 전환 + mysqldump 일괄 이관 · 쓰기 중단 수 초 · RDS 8.4.11 |
V2를 운영하면서 장애를 사용자보다 먼저 알기 위한 관측·알림 설계입니다.
| 문서 | 요약 | 최종 결정 |
|---|---|---|
| V2 중앙 집중식 모니터링 시스템 설계 | V2 요구사항에서 모니터링이 답할 질문, 구조 후보 4개 비교, 로그·메트릭 수집 방식과 V2 구조 안의 배치 | PLG(Prometheus·Loki·Grafana) + Alloy, 트레이스는 Sentry · 모니터링 EC2 1대 |
| V2 서비스 장애 알림 체계 설계 | 요청 경로의 장애 판단 지점 6곳, CloudWatch·Grafana 두 알림 경로, 규칙·채널 라우팅·켜는 순서 | CloudWatch Alarm → EventBridge → Discord + Grafana 규칙 6개 · prod page는 #incident |
0. 서비스와 팀 운영 가정
2. CI 파이프라인
3. CD 파이프라인
4. CUJ와 SLI/SLO
6. V2 인프라 설계
- Nginx → CloudFront·ALB
- DB → RDS MySQL
- 백엔드 → ECS on EC2
- WebSocket → Redis Pub/Sub
- ECS 기반 전체 아키텍처
- ECS Task Auto Scaling
- DB 무중단 마이그레이션
13: 13단계 · 4: 1단계 · 5~7: 4단계