Skip to content

f-lab-edu/creatorhub-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

249 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Creatorhub

์›นํˆฐ ์ž‘๊ฐ€์™€ ๋…์ž๋ฅผ ์œ„ํ•œ ์›นํˆฐ ํ”Œ๋žซํผ์˜ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋กœ ์ž‘ํ’ˆ ์—…๋กœ๋“œ, ์ž‘ํ’ˆ ๋ทฐ, ๊ฒฐ์ œ ์‹œ์Šคํ…œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

demo

์ฃผ์š”๊ธฐ๋Šฅ

๐Ÿ‘จโ€๐ŸŽจ ์ž‘๊ฐ€ ๊ธฐ๋Šฅ

  • ์ž‘ํ’ˆ ๋“ฑ๋ก / ํšŒ์ฐจ ๋“ฑ๋ก

๐Ÿ“š ๋…์ž ๊ธฐ๋Šฅ

  • ์š”์ผ๋ณ„ ์ž‘ํ’ˆ ์กฐํšŒ(์ธ๊ธฐ์ˆœ, ์กฐํšŒ์ˆ˜, ๋ณ„์ ์ˆœ)
  • ์ž‘ํ’ˆ ๋ฐ ํšŒ์ฐจ ์ƒ์„ธ ์กฐํšŒ
  • ๊ด€์‹ฌ ์ž‘ํ’ˆ ๋“ฑ๋ก / ํšŒ์ฐจ๋ณ„ ํ‰์ , ์ข‹์•„์š” ๋“ฑ๋ก

๐Ÿ’ณ ๊ฒฐ์ œ ์‹œ์Šคํ…œ(์ง„ํ–‰์ค‘)

  • Toss Payments ๊ฒฐ์ œ ๋ฐ ์ฝ”์ธ ์ถฉ์ „

๐Ÿ› ๏ธ ๊ธฐ์ˆ  ์Šคํƒ

Backend

  • Spring Boot 3.5.7, MySQL 8.0, Redis 7.2-alpine, Gradle 8.14.3
  • Spring Data JPA, Flyway (DB Migration)

Infra

  • AWS (S3, Lambda, SQS, SNS, CloudFront)
  • Github Actions (CI/CD)
  • Docker Compose (๋ฐฐํฌ, ์‹คํ–‰)
  • Prometheus + Grafana(๋ชจ๋‹ˆํ„ฐ๋ง), k6(๋ถ€ํ•˜ํ…Œ์ŠคํŠธ)

Frontend

  • React, TypeScript, Axios, Tailwind CSS
  • Claude AI๋ฅผ ํ™œ์šฉํ•œ ํ”„๋กœํ† ํƒ€์ดํ•‘ ๋ฐ ๋ฐ˜๋ณต ์ž‘์—… ์ž๋™ํ™”

โ˜๏ธ ์•„ํ‚คํ…์ณ ๋‹ค์ด์–ด๊ทธ๋žจ

์•„ํ‚คํ…์ณ


๐Ÿ—„๏ธ ERD

โœ๏ธ ERD ์ƒ์„ธ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

erd


๐Ÿ“ฆ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

1) Application

src/
โ””โ”€ main/
   โ”œโ”€ java/
   โ””โ”€ resources/
  • ๋„๋ฉ”์ธ ์ค‘์‹ฌ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ
  • application-{env}.yml ๊ธฐ๋ฐ˜ ํ™˜๊ฒฝ ๋ถ„๋ฆฌ

2) Infra

infra/
โ””โ”€ lambda-image-resize/
  • Lambda ๊ธฐ๋ฐ˜ ์ด๋ฏธ์ง€ ๋ฆฌ์‚ฌ์ด์ง• ๋ฐ ์—…๋กœ๋“œ ์ฒ˜๋ฆฌ

3) Performance & Monitoring

k6/
  • k6 ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ + Prometheus/Grafana ๋ชจ๋‹ˆํ„ฐ๋ง

4) Deployment

docker-compose*.yml
.env
  • Docker Compose ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ, ์šด์˜

โญ ISSUE ๋ฐ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

1. ์ธ๋„ค์ผ/์›๊ณ  ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ

โœ๏ธ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ • ์ƒ์„ธ๋ณด๊ธฐ

  • ๋ฌธ์ œ: ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ, ๋ฆฌ์‚ฌ์ด์ง•์„ ์„œ๋ฒ„์—์„œ ์ง์ ‘ ์ฒ˜๋ฆฌ์‹œ ๋ถ€ํ•˜ ์ฆ๊ฐ€
  • ํ•ด๊ฒฐ: 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, ์žฌ์‹œ๋„, ํƒ€์ž„์•„์›ƒ ๊ด€๋ฆฌ ๋“ฑ์˜ ๋กœ์ง์„ ์ œ๊ฑฐํ•ด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ๊ตฌํ˜„ ๋‹จ์ˆœํ™” ๊ฐ€๋Šฅ

2. JWT + Redis ๊ธฐ๋ฐ˜ ์ธ์ฆ

โœ๏ธ ์ธ์ฆ์‹œ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ • ์ƒ์„ธ๋ณด๊ธฐ

  • ๋ฌธ์ œ: ์„ธ์…˜๋ฐฉ์‹๊ณผ JWT ๋ฐฉ์‹์ค‘ ์ธ์ฆ๋ฐฉ์‹ ์„ ํƒ ํ•„์š”
  • ํ•ด๊ฒฐ: ์ฐจํ›„ ์„œ๋ฒ„์˜ ์ˆ˜ํ‰ ํ™•์žฅ(Scale-out) ๊ณ ๋ ค์‹œ ์šด์˜ ๋ถ€๋‹ด์ด ์ปค์ ธ JWT ๋ฐฉ์‹ ์„ ํƒ

  • ๋ฌธ์ œ: Refresh Token ์ €์žฅ์†Œ๋กœ RDB ๋˜๋Š” Redis ์ค‘ ์„ ํƒ ํ•„์š”
  • ํ•ด๊ฒฐ: TTL ๊ธฐ๋ฐ˜ ์ž๋™ ๋งŒ๋ฃŒ๋กœ ํ† ํฐ ์ •๋ฆฌ ์ž‘์—…์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด Redis ์„ ํƒ

3. ์š”์ผ๋ณ„ ์›นํˆฐ ์กฐํšŒ์‹œ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ

  • ๋ฌธ์ œ: Offset ํŽ˜์ด์ง•์€ ๋ฐ์ดํ„ฐ ์ฆ๊ฐ€ ์‹œ ์„ฑ๋Šฅ ์ €ํ•˜ ๋ฐœ์ƒ
  • ํ•ด๊ฒฐ: Cursor ํŽ˜์ด์ง• ์ ์šฉ

4. ๋™์‹œ์„ฑ ๋ฌธ์ œ ๋ฐœ์ƒ

  • ๋ฌธ์ œ: ๊ด€์‹ฌ์ž‘ํ’ˆ, ์ข‹์•„์š” ๋“ฑ ์‚ฌ์šฉ์ž์˜ ์‚ฌ์šฉ ์‹ค์ˆ˜๋กœ ๋™์‹œ ์š”์ฒญ์‹œ ์ค‘๋ณต๋ฐ์ดํ„ฐ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
  • ํ•ด๊ฒฐ: DB Unique ์ œ์•ฝ์กฐ๊ฑด + ์›์ž์  ์—…๋ฐ์ดํŠธ ์ฟผ๋ฆฌ ์‚ฌ์šฉ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ํ™•๋ณด

5. DB ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ

  • ๋ฌธ์ œ: DB ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ์ด๋ ฅ ๊ด€๋ฆฌ ํ•„์š”
  • ํ•ด๊ฒฐ: ๋ฒ„์ „ ๊ธฐ๋ฐ˜ ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ, ํ™˜๊ฒฝ ๊ฐ„ DB ๋ถˆ์ผ์น˜ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด Flyway ์‚ฌ์šฉ

โญ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๋ฐ ๊ฐœ์„ 

  • Prometheus, Grafana๋ฅผ ํ†ตํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง ํ™˜๊ฒฝ ๊ตฌํ˜„ + k6 ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ
  • Creations(์ž‘ํ’ˆ): 7,000๊ฑด / Episodes(ํšŒ์ฐจ): 518,146๊ฑด

1. ์š”์ผ๋ณ„ ์›นํˆฐ ์กฐํšŒ API

โœ๏ธ ์ž์„ธํ•œ ์„ฑ๋Šฅ ๋ถ„์„ ๊ณผ์ •๋ณด๊ธฐ

๊ฐœ์„  ๊ฒฐ๊ณผ

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 ๊ตฌ์กฐ ๊ฐœ์„ 

2. ํŠน์ • ํšŒ์ฐจ ์›นํˆฐ ์กฐํšŒ API

โœ๏ธ ์ž์„ธํ•œ ์„ฑ๋Šฅ ๋ถ„์„ ๊ณผ์ •๋ณด๊ธฐ

๊ฐœ์„  ๊ฒฐ๊ณผ

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) ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝ

โš™๏ธ ์„ค๊ณ„ ๊ทœ์น™

1. DB / Entity ์„ค๊ณ„ ์ •์ฑ…

โœ๏ธ RDB ์„ค๊ณ„ ์›์น™๊ณผ ์ œ์•ฝ์กฐ๊ฑด ์ƒ์„ธ๋ณด๊ธฐ

  • ๋„๋ฉ”์ธ ์‹๋ณ„์ž ๋ฐ ์‚ฌ์šฉ์ž ์•ก์…˜(์ข‹์•„์š”, ๊ด€์‹ฌ์ž‘ํ’ˆ, ํ‰์  ๋“ฑ)์€ DB UNIQUE ์ œ์•ฝ์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ๊ณผ ๋ฉฑ๋“ฑ์„ฑ ๋ณด์žฅ
  • Enum ๊ฐ’์€ DB์— VARCHAR๋กœ ์ €์žฅํ•˜์—ฌ ์ฝ”๋“œ Enum ๋ณ€๊ฒฝ์ด DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์œผ๋กœ ํ™•์žฅ๋˜๋Š” ๊ฒƒ ๋ฐฉ์ง€
  • ์ธ๋„ค์ผ ๋ฐ ์›๊ณ  ์ด๋ฏธ์ง€๋Š” display_order๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ์ˆœ์„œ ์ถฉ๋Œ ๋ฐ ์ค‘๋ณต ๋ฐ์ดํ„ฐ ๋ฐฉ์ง€

โœ๏ธ Index ์ •์ฑ… ์ƒ์„ธ๋ณด๊ธฐ

  • ์ธ๋ฑ์Šค๋Š” ์ปฌ๋Ÿผ์ด ์•„๋‹Œ ์‹ค์ œ ์กฐํšŒ ํŒจํ„ด(WHERE + ORDER BY)์„ ๊ธฐ์ค€์œผ๋กœ ์„ค๊ณ„
  • ์ •๋ ฌ๊ณผ ํŽ˜์ด์ง• ์„ฑ๋Šฅ์„ ์œ„ํ•ด ๋ณตํ•ฉ ์ธ๋ฑ์Šค์™€ UNIQUE ์ œ์•ฝ์„ ํ™œ์šฉํ•˜์—ฌ ์ •๋ ฌ ๋น„์šฉ ์ตœ์†Œํ™”

โœ๏ธ Entity ์ •์ฑ… ์ƒ์„ธ๋ณด๊ธฐ

  • JPA ์—ฐ๊ด€๊ด€๊ณ„๋Š” ๋‹จ๋ฐฉํ–ฅ ์šฐ์„  ์ „๋žต์„ ์ ์šฉํ•˜๊ณ , ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ '์–‘๋ฐฉํ–ฅ + cascade/orphanRemoval' ์‚ฌ์šฉ

2. ์ธ์ฆ ์ •์ฑ…

  • Spring Security ๊ธฐ๋ฐ˜ ์ธ์ฆ ๊ตฌ์กฐ: JWT ์ธ์ฆ + Role ๊ธฐ๋ฐ˜ ์ธ์ฆ
  • Lambda ์ฝœ๋ฐฑ HMAC ์ธ์ฆ: Lambda ์ด๋ฏธ์ง€ ๋ฆฌ์‚ฌ์ด์ง• ์™„๋ฃŒ์‹œ ๋ฐฑ์—”๋“œ ์ฝœ๋ฐฑ ์š”์ฒญ์— ๋Œ€ํ•ด HMAC ์ธ์ฆ ์ ์šฉ โ†’ ์™ธ๋ถ€ ์š”์ฒญ ์œ„๋ณ€์กฐ ๋ฐฉ์ง€

๐Ÿณ Docker ๊ธฐ๋ฐ˜ ์‹คํ–‰ ๋ฐ CI/CD ๋ฐฐํฌ

  • Docker Compose๋กœ ์‹คํ–‰๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ: MySQL, Redis, Spring Boot ์•ฑ(creatorhub-server), Prometheus, Grafana
  • ๋ชจ๋“  ๋ฏผ๊ฐํ•œ ์„ค์ • ๊ฐ’์€ ์‹คํ–‰ ์‹œ ํ™˜๊ฒฝ๋ณ€์ˆ˜(.env)๋กœ ์ฃผ์ž…
  • GitHub Actions๋ฅผ ํ†ตํ•ด ์ž๋™ํ™”๋œ Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ ์ง„ํ–‰(CI/CD)
    • main ๋ธŒ๋žœ์น˜์— PR merge โ†’ Docker ์ด๋ฏธ์ง€ ์ƒ์„ฑ โ†’ GHCR์— ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ โ†’ EC2 ์ž๋™ ๋ฐฐํฌ

๐Ÿ’ก๊ฐœ๋ฐœ ์‹คํ–‰ ๊ฐ€์ด๋“œ ๋ณด๊ธฐ
๐Ÿ’ก์ˆ˜๋™ ๋ฐฐํฌ ๊ฐ€์ด๋“œ ๋ณด๊ธฐ(์ฐธ๊ณ )

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors