์นํฐ ์๊ฐ์ ๋
์๋ฅผ ์ํ ์นํฐ ํ๋ซํผ์ ๋ฐฑ์๋ ์๋ฒ๋ก ์ํ ์
๋ก๋, ์ํ ๋ทฐ, ๊ฒฐ์ ์์คํ
๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ์ํ ๋ฑ๋ก / ํ์ฐจ ๋ฑ๋ก
- ์์ผ๋ณ ์ํ ์กฐํ(์ธ๊ธฐ์, ์กฐํ์, ๋ณ์ ์)
- ์ํ ๋ฐ ํ์ฐจ ์์ธ ์กฐํ
- ๊ด์ฌ ์ํ ๋ฑ๋ก / ํ์ฐจ๋ณ ํ์ , ์ข์์ ๋ฑ๋ก
- Toss Payments ๊ฒฐ์ ๋ฐ ์ฝ์ธ ์ถฉ์
- Spring Boot 3.5.7, MySQL 8.0, Redis 7.2-alpine, Gradle 8.14.3
- Spring Data JPA, Flyway (DB Migration)
- AWS (S3, Lambda, SQS, SNS, CloudFront)
- Github Actions (CI/CD)
- Docker Compose (๋ฐฐํฌ, ์คํ)
- Prometheus + Grafana(๋ชจ๋ํฐ๋ง), k6(๋ถํํ ์คํธ)
- React, TypeScript, Axios, Tailwind CSS
- Claude AI๋ฅผ ํ์ฉํ ํ๋กํ ํ์ดํ ๋ฐ ๋ฐ๋ณต ์์ ์๋ํ
โ๏ธ ERD ์์ธ ๋ณด๋ฌ๊ฐ๊ธฐ
src/
โโ main/
โโ java/
โโ resources/
- ๋๋ฉ์ธ ์ค์ฌ ํจํค์ง ๊ตฌ์กฐ
- application-{env}.yml ๊ธฐ๋ฐ ํ๊ฒฝ ๋ถ๋ฆฌ
infra/
โโ lambda-image-resize/
- Lambda ๊ธฐ๋ฐ ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง ๋ฐ ์ ๋ก๋ ์ฒ๋ฆฌ
k6/
- k6 ๋ถํ ํ ์คํธ + Prometheus/Grafana ๋ชจ๋ํฐ๋ง
docker-compose*.yml
.env
- Docker Compose ๊ธฐ๋ฐ ๊ฐ๋ฐ, ์ด์
โ๏ธ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ๋ฌธ์ ํด๊ฒฐ ๊ณผ์ ์์ธ๋ณด๊ธฐ
- ๋ฌธ์ : ์ด๋ฏธ์ง ์ ๋ก๋, ๋ฆฌ์ฌ์ด์ง์ ์๋ฒ์์ ์ง์ ์ฒ๋ฆฌ์ ๋ถํ ์ฆ๊ฐ
- ํด๊ฒฐ: S3 + Presigned URL๋ฅผ ์ฌ์ฉํ ํ๋ก ํธ์๋์์ ์ ๋ก๋, Lambda ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง ์ ์ฉ์ผ๋ก ์๋ฒ ๊ฐ์ฉ์ฑ ํ๋ณด
- ๋ฌธ์ : Lambda ๋ฆฌ์ฌ์ด์ง ์คํจ์ ์ฌ์ฒ๋ฆฌ
- ํด๊ฒฐ:
- ๋ฉ์ธ์งํ(SQS)๋ฅผ ์ด์ฉํด Lambda ์์ ํ์ ์คํจ๋ ์์ ์ด ์ ์ฅ๋๋ ํ(DLQ)๋ฅผ ๊ฐ๊ฐ ๋ง๋ฌ
- S3 ์ ๋ก๋ โ Lambda ์์ ํ(SQS) โ Lambda ํธ๋ฆฌ๊ฑฐ
- ์์ ํ๋ฅผ ์ด์ฉํด 3๋ฒ ์ฌ์๋ ํ ์คํจ ์์์๋ DLQ๋ก ์ด๋, ์ดํ SNS๋ก slack ์๋
- ๋ฌธ์ : ์ ๋ก๋ ํ ์ด๋ฏธ์ง ์ฒซ ๋ ธ์ถ์ ์ง์ฐ ๋ฌธ์
- ํด๊ฒฐ: CDN(CloudFront) ์ ์ฌ์ฉํด ์ง์ฐ ์ต์ํ
- ๋ฌธ์ : ๋น๋๊ธฐ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ์๋ฃ ์ฌ๋ถ๋ฅผ ํด๋ผ์ด์ธํธ๊ฐ ํ์ธํ๊ธฐ ์ด๋ ค์ โ Polling๊ณผ SSE ์ค ์ ํ ํ์
- ํด๊ฒฐ:
- Lambda โ Backend Callback โ SSE ์๋ฆผ ๊ตฌ์กฐ ์ ์ฉ์ ํตํด ๋ถํ์ํ ํธ๋ํฝ์ ์ค์
- Polling์ interval, ์ฌ์๋, ํ์์์ ๊ด๋ฆฌ ๋ฑ์ ๋ก์ง์ ์ ๊ฑฐํด ํด๋ผ์ด์ธํธ ์ฝ๋ ๊ตฌํ ๋จ์ํ ๊ฐ๋ฅ
โ๏ธ ์ธ์ฆ์ ๋ฌธ์ ํด๊ฒฐ ๊ณผ์ ์์ธ๋ณด๊ธฐ
- ๋ฌธ์ : ์ธ์ ๋ฐฉ์๊ณผ JWT ๋ฐฉ์์ค ์ธ์ฆ๋ฐฉ์ ์ ํ ํ์
- ํด๊ฒฐ: ์ฐจํ ์๋ฒ์ ์ํ ํ์ฅ(Scale-out) ๊ณ ๋ ค์ ์ด์ ๋ถ๋ด์ด ์ปค์ ธ JWT ๋ฐฉ์ ์ ํ
- ๋ฌธ์ : Refresh Token ์ ์ฅ์๋ก RDB ๋๋ Redis ์ค ์ ํ ํ์
- ํด๊ฒฐ: TTL ๊ธฐ๋ฐ ์๋ ๋ง๋ฃ๋ก ํ ํฐ ์ ๋ฆฌ ์์ ์ ์ต์ํํ๊ธฐ ์ํด Redis ์ ํ
- ๋ฌธ์ : Offset ํ์ด์ง์ ๋ฐ์ดํฐ ์ฆ๊ฐ ์ ์ฑ๋ฅ ์ ํ ๋ฐ์
- ํด๊ฒฐ: Cursor ํ์ด์ง ์ ์ฉ
- ๋ฌธ์ : ๊ด์ฌ์ํ, ์ข์์ ๋ฑ ์ฌ์ฉ์์ ์ฌ์ฉ ์ค์๋ก ๋์ ์์ฒญ์ ์ค๋ณต๋ฐ์ดํฐ ๋ฐ์ ๊ฐ๋ฅ
- ํด๊ฒฐ: DB Unique ์ ์ฝ์กฐ๊ฑด + ์์์ ์ ๋ฐ์ดํธ ์ฟผ๋ฆฌ ์ฌ์ฉ์ผ๋ก ๋ฐ์ดํฐ ์ผ๊ด์ฑ ํ๋ณด
- ๋ฌธ์ : DB ์คํค๋ง ๋ณ๊ฒฝ ์ด๋ ฅ ๊ด๋ฆฌ ํ์
- ํด๊ฒฐ: ๋ฒ์ ๊ธฐ๋ฐ ์คํค๋ง ๊ด๋ฆฌ, ํ๊ฒฝ ๊ฐ DB ๋ถ์ผ์น ๋ฐฉ์ง๋ฅผ ์ํด Flyway ์ฌ์ฉ
- Prometheus, Grafana๋ฅผ ํตํ ๋ชจ๋ํฐ๋ง ํ๊ฒฝ ๊ตฌํ + k6 ๋ถํ ํ ์คํธ
- Creations(์ํ): 7,000๊ฑด / Episodes(ํ์ฐจ): 518,146๊ฑด
โ๏ธ ์์ธํ ์ฑ๋ฅ ๋ถ์ ๊ณผ์ ๋ณด๊ธฐ
| Metric | Before | After |
|---|---|---|
| Throughput(TPS) | 93 req/s | 1,094 req/s (11.7๋ฐฐ ์ฆ๊ฐ) |
| P95 Latency | 3.13 s | 297ms (90% ๋นจ๋ผ์ง) |
- Creation ํ ์ด๋ธ ๋น์ ๊ทํ (์ฌ์ ์ง๊ณ ์ปฌ๋ผ ์์ฑ)
- Episode ํ ์ด๋ธ์ 'JOIN + GROUP BY' ์ง๊ณ ์ ๊ฑฐ
- ์ฟผ๋ฆฌ 3ํ ์กฐํ(select) โ 1ํ ์กฐํ๋ก ํตํฉ
- HikariCP ์ปค๋ฅ์ ํ, Mysql DB ๋ฉ๋ชจ๋ฆฌ ํ๋
- JPQL โ Native Query ๋ณ๊ฒฝ ๋ฐ JOIN ๊ตฌ์กฐ ๊ฐ์
โ๏ธ ์์ธํ ์ฑ๋ฅ ๋ถ์ ๊ณผ์ ๋ณด๊ธฐ
| Metric | Before | After |
|---|---|---|
| Throughput(TPS) | 151 req/s | 2,748.5 req/s (18๋ฐฐ ์ฆ๊ฐ) |
| P95 Latency | 1.97 s | 131.98ms (93% ๋นจ๋ผ์ง) |
- ์กฐํ์ ์ฆ๊ฐ ์ Redis์ ์ง๊ณ ํ, 10์ด ์ฃผ๊ธฐ ๋ฐฐ์น๋ก DB์ ๋ฐ์ํ์ฌ UPDATE Lock ๊ฒฝ์ ์ ๊ฑฐ
- Caffeine ์บ์ ์ ์ฉ ๋ฐ ์บ์ ์คํฌํผ๋ ์ํ(ํ์ฐจ ๋ฐ์ดํฐ๋ ๋ณ๊ฒฝ ๋น๋๊ฐ ๋ฎ์)
- SUM(view_count) ์ง๊ณ ์ฟผ๋ฆฌ๋ฅผ ๋จ์ ์ฆ๊ฐ(+1) ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝ
โ๏ธ RDB ์ค๊ณ ์์น๊ณผ ์ ์ฝ์กฐ๊ฑด ์์ธ๋ณด๊ธฐ
- ๋๋ฉ์ธ ์๋ณ์ ๋ฐ ์ฌ์ฉ์ ์ก์
(์ข์์, ๊ด์ฌ์ํ, ํ์ ๋ฑ)์ DB
UNIQUE์ ์ฝ์ผ๋ก ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ๊ณผ ๋ฉฑ๋ฑ์ฑ ๋ณด์ฅ - Enum ๊ฐ์ DB์
VARCHAR๋ก ์ ์ฅํ์ฌ ์ฝ๋ Enum ๋ณ๊ฒฝ์ด DB ๋ง์ด๊ทธ๋ ์ด์ ์ผ๋ก ํ์ฅ๋๋ ๊ฒ ๋ฐฉ์ง - ์ธ๋ค์ผ ๋ฐ ์๊ณ ์ด๋ฏธ์ง๋ display_order๋ก ๊ด๋ฆฌํ์ฌ ์์ ์ถฉ๋ ๋ฐ ์ค๋ณต ๋ฐ์ดํฐ ๋ฐฉ์ง
โ๏ธ Index ์ ์ฑ
์์ธ๋ณด๊ธฐ
- ์ธ๋ฑ์ค๋ ์ปฌ๋ผ์ด ์๋ ์ค์ ์กฐํ ํจํด(WHERE + ORDER BY)์ ๊ธฐ์ค์ผ๋ก ์ค๊ณ
- ์ ๋ ฌ๊ณผ ํ์ด์ง ์ฑ๋ฅ์ ์ํด ๋ณตํฉ ์ธ๋ฑ์ค์ UNIQUE ์ ์ฝ์ ํ์ฉํ์ฌ ์ ๋ ฌ ๋น์ฉ ์ต์ํ
โ๏ธ Entity ์ ์ฑ
์์ธ๋ณด๊ธฐ
- JPA ์ฐ๊ด๊ด๊ณ๋ ๋จ๋ฐฉํฅ ์ฐ์ ์ ๋ต์ ์ ์ฉํ๊ณ , ์๋ช ์ฃผ๊ธฐ ๊ด๋ฆฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ์๋ง '์๋ฐฉํฅ + cascade/orphanRemoval' ์ฌ์ฉ
- Spring Security ๊ธฐ๋ฐ ์ธ์ฆ ๊ตฌ์กฐ: JWT ์ธ์ฆ + Role ๊ธฐ๋ฐ ์ธ์ฆ
- Lambda ์ฝ๋ฐฑ HMAC ์ธ์ฆ: Lambda ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง ์๋ฃ์ ๋ฐฑ์๋ ์ฝ๋ฐฑ ์์ฒญ์ ๋ํด HMAC ์ธ์ฆ ์ ์ฉ โ ์ธ๋ถ ์์ฒญ ์๋ณ์กฐ ๋ฐฉ์ง
- Docker Compose๋ก ์คํ๋๋ ์ปจํ ์ด๋: MySQL, Redis, Spring Boot ์ฑ(creatorhub-server), Prometheus, Grafana
- ๋ชจ๋ ๋ฏผ๊ฐํ ์ค์ ๊ฐ์ ์คํ ์ ํ๊ฒฝ๋ณ์(.env)๋ก ์ฃผ์
- GitHub Actions๋ฅผ ํตํด ์๋ํ๋ Docker ์ด๋ฏธ์ง ๋น๋ ๋ฐ ๋ฐฐํฌ ์งํ(CI/CD)
- main ๋ธ๋์น์ PR merge โ Docker ์ด๋ฏธ์ง ์์ฑ โ GHCR์ ์ด๋ฏธ์ง ์ ๋ก๋ โ EC2 ์๋ ๋ฐฐํฌ
๐ก๊ฐ๋ฐ ์คํ ๊ฐ์ด๋ ๋ณด๊ธฐ
๐ก์๋ ๋ฐฐํฌ ๊ฐ์ด๋ ๋ณด๊ธฐ(์ฐธ๊ณ )


