๐ŸŽซ ์ถ•์ œ์˜ ๋ฏผ์กฑ

๐Ÿ“Œ ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

์ด ํ”„๋กœ์ ํŠธ๋Š” ์ œํ•œ๋œ ๋ฆฌ์†Œ์Šค ํ™˜๊ฒฝ(AWS t3.small EC2 ์ธ์Šคํ„ด์Šค 2๋Œ€, RDS, Redis)์—์„œ ์•ˆ์ •์ ์ธ ์šด์˜์„ ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ๊ณ ์„ฑ๋Šฅ ํŽ˜์Šคํ‹ฐ๋ฒŒ ํ‹ฐ์ผ“ ์˜ˆ๋งค ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. ์ˆœ๊ฐ„์ ์ธ ๋Œ€๊ทœ๋ชจ ํŠธ๋ž˜ํ”ฝ ์ƒํ™ฉ์—์„œ๋„ ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ, ํšจ์œจ์ ์ธ ๋Œ€๊ธฐ์—ด ๊ด€๋ฆฌ์™€ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ๋ชฉํ‘œ

  • ์„œ๋ฒ„ ์•ˆ์ •์„ฑ ํ™•๋ณด: CPU ์‚ฌ์šฉ๋ฅ  ํ”ผํฌ ์‹œ 80% ์ดํ•˜ ์œ ์ง€
  • ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์ตœ์ ํ™”: ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„ 5์ดˆ ์ด๋‚ด ์œ ์ง€ (ํ‹ฐ์ผ“ ์กฐํšŒ๋ถ€ํ„ฐ ๊ฒฐ์ œ๊นŒ์ง€)

๐Ÿš€ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

  1. ์‹ค์‹œ๊ฐ„ ๋Œ€๊ธฐ์—ด ์‹œ์Šคํ…œ: Redis ๊ธฐ๋ฐ˜์˜ ๊ณต์ •ํ•œ ๋Œ€๊ธฐ์—ด ๊ด€๋ฆฌ
  2. ํšจ์œจ์ ์ธ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ: ๋น„๋™๊ธฐ ๋ฐฉ์‹์˜ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ๋ฐ ์ฃผ๊ธฐ์  ์ƒํƒœ ์กฐํšŒ
  3. ์‹ค์‹œ๊ฐ„ ํ‹ฐ์ผ“ ์ ์œ  ๋ฐ ๊ฒฐ์ œ ๊ธฐํšŒ ๋ณด์žฅ: Redis ๊ธฐ๋ฐ˜ ํ‹ฐ์ผ“ ์žฌ๊ณ  ์ ์œ  ์‹œ์Šคํ…œ
  4. ๋น„๋™๊ธฐ ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ: ์ธ๋ฉ”๋ชจ๋ฆฌ ํ ์‹œ์Šคํ…œ์„ ํ†ตํ•œ ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ ์ตœ์ ํ™”

๐Ÿ‘€ ๋ฐ๋ชจ

๋ฉ”์ธ ํ™”๋ฉด

๋ฉ”์ธํŽ˜์ด์ง€

๋งˆ์ด ํŽ˜์ด์ง€

๋งˆ์ดํŽ˜์ด์ง€

๊ตฌ๋งค ํŽ˜์ด์ง€

๊ตฌ๋งค ์„ฑ๊ณต

์–ด๋“œ๋ฏผ ํŽ˜์ด์ง€

์–ด๋“œ๋ฏผ ํŽ˜์ด์ง€

์ฒดํฌ์ธ

๋งˆ์ดํŽ˜์ด์ง€

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

Java Spring MySQL Redis Gradle Grafana Prometheus k6

๐Ÿ“ ์•„ํ‚คํ…์ฒ˜

์•„ํ‚คํ…์ฒ˜.png

๐Ÿ”ง ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ

1. ๋Œ€๊ธฐ์—ด ์‹œ์Šคํ…œ (WaitOrderService)

  • ์›๋ฆฌ: ์ฒญํฌ ๊ธฐ๋ฐ˜์˜ ๋Œ€๊ธฐ์—ด ๊ด€๋ฆฌ ์‹œ์Šคํ…œ
  • ๋Œ€๊ธฐ์—ด ๊ด€๋ฆฌ:
    • Redis Set์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ํ‹ฐ์ผ“์— ๋Œ€ํ•œ ๋Œ€๊ธฐ์—ด ์œ ์ง€
    • ์‚ฌ์šฉ์ž ์ง„์ž… ์‹œ ํ˜„์žฌ ๋Œ€๊ธฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋Œ€๊ธฐ ์ˆœ์„œ ํ• ๋‹น
  • ์ž…์žฅ ๊ด€๋ฆฌ:
    • passChunkSize ๋‹จ์œ„๋กœ ์ž…์žฅ ๊ฐ€๋Šฅํ•œ ๋ฒ”์œ„ ๊ด€๋ฆฌ
    • ์ฃผ๊ธฐ์ ์œผ๋กœ ์ž…์žฅ ๊ฐ€๋Šฅ ๋ฒ”์œ„๋ฅผ passChunkSize๋งŒํผ ์ฆ๊ฐ€์‹œ์ผœ ์ˆœ์ฐจ์  ์ž…์žฅ ํ—ˆ์šฉ
  • ์ƒํƒœ ํ™•์ธ ๋ฐ ์—…๋ฐ์ดํŠธ:
    • ์‚ฌ์šฉ์ž์˜ ๋Œ€๊ธฐ ์ˆœ์„œ๊ฐ€ ํ˜„์žฌ ์ž…์žฅ ๊ฐ€๋Šฅ ๋ฒ”์œ„ ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธ
    • ์žฌ๊ณ  ์—ฌ๋ถ€๋„ ํ•จ๊ป˜ ์ฒดํฌํ•˜์—ฌ ์ž…์žฅ ๊ฐ€๋Šฅ ์—ฌ๋ถ€์™€ ๋‚จ์€ ๋Œ€๊ธฐ ์ธ์› ์ˆ˜ ์ œ๊ณต

2. ๊ฒฐ์ œ ์‹œ์Šคํ…œ (PurchaseFacadeService, PaymentService)

  • ์›๋ฆฌ: ๋น„๋™๊ธฐ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ๋ฐ ์ƒํƒœ ๊ด€๋ฆฌ
  • ๊ฒฐ์ œ ํ”„๋กœ์„ธ์Šค:
    • ๊ฒฐ์ œ ์š”์ฒญ ์‹œ UUID ๊ธฐ๋ฐ˜์˜ ๊ฒฐ์ œ ID ์ƒ์„ฑ ํ›„ ๋น„๋™๊ธฐ๋กœ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ์‹œ์ž‘
    • CompletableFuture๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ๊ตฌํ˜„
  • ์ƒํƒœ ๊ด€๋ฆฌ:
    • Caffeine ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ์ œ ์ƒํƒœ ๊ด€๋ฆฌ
    • ๊ฒฐ์ œ ID๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ์ œ ์ •๋ณด ๋ฐ ์ƒํƒœ ์ €์žฅ
  • ๊ฒฐ์ œ ์™„๋ฃŒ ํ›„ ์ฒ˜๋ฆฌ:
    • ๊ฒฐ์ œ ์„ฑ๊ณต ์‹œ QueueService๋ฅผ ํ†ตํ•ด ๊ตฌ๋งค ์ •๋ณด ์ฒ˜๋ฆฌ
    • ๊ฒฐ์ œ ์‹คํŒจ ์‹œ CompensationService๋ฅผ ํ†ตํ•ด ์žฌ๊ณ  ๋ฐ ์ƒํƒœ ๋กค๋ฐฑ

3. ์žฌ๊ณ  ๊ด€๋ฆฌ (TicketStockCountRedisRepository)

  • ์›๋ฆฌ: Redis๋ฅผ ํ™œ์šฉํ•œ ์‹ค์‹œ๊ฐ„ ์žฌ๊ณ  ๊ด€๋ฆฌ
  • ์žฌ๊ณ  ๊ด€๋ฆฌ:
    • Redis์— ๊ฐ ํ‹ฐ์ผ“์˜ ์žฌ๊ณ  ์ˆ˜๋Ÿ‰ ์ €์žฅ
    • ์›์ž์  ๊ฐ์†Œ ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ
  • ์žฌ๊ณ  ๋™๊ธฐํ™”:
    • TicketScheduleService๋ฅผ ํ†ตํ•ด ํŒ๋งค ์ „์— Redis์˜ ์žฌ๊ณ  ์ •๋ณด ์—…๋ฐ์ดํŠธ

4. ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ (QueueService)

  • ์›๋ฆฌ: ์ธ๋ฉ”๋ชจ๋ฆฌ ํ๋ฅผ ํ™œ์šฉํ•œ ๋น„๋™๊ธฐ ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ
  • ์ฃผ๋ฌธ ์ ‘์ˆ˜:
    • InMemoryQueue์— ๊ตฌ๋งค ๋ฐ์ดํ„ฐ(PurchaseData) ์ €์žฅ
    • ํ๊ฐ€ ๊ฐ€๋“ ์ฐผ์„ ๊ฒฝ์šฐ ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„๋ฅผ ์ ์šฉํ•œ ์žฌ์‹œ๋„ ๋กœ์ง ๊ตฌํ˜„
  • ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ:
    • ์ฃผ๊ธฐ์ ์œผ๋กœ(5์ดˆ๋งˆ๋‹ค) ํ์—์„œ ๋ฐฐ์น˜ ๋‹จ์œ„๋กœ ์ฃผ๋ฌธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ
    • ๋ฐฐ์น˜ ํฌ๊ธฐ๋Š” ํ์˜ ํ˜„์žฌ ํฌ๊ธฐ์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ์กฐ์ •
  • ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ:
    • ์ฃผ๋ฌธ ์ •๋ณด์™€ ์ฒดํฌ์ธ ์ •๋ณด๋ฅผ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์–ด ์ผ๊ด„ ์ฒ˜๋ฆฌ
    • JDBC batch update๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ์‚ฐ ์ตœ์ ํ™”
  • ์žฅ์•  ๋ณต๊ตฌ:
    • ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์‹œ ๋กœ๊ทธ ํŒŒ์ผ์„ ๋ถ„์„ํ•˜์—ฌ ๋ฏธ์ฒ˜๋ฆฌ๋œ ์ฃผ๋ฌธ ๋ณต๊ตฌ
    • ์ฒ˜๋ฆฌ ์‹คํŒจํ•œ ์ฃผ๋ฌธ์— ๋Œ€ํ•œ ์žฌ์‹œ๋„ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๊ตฌํ˜„

๐Ÿ“ˆ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์ „๋žต

  1. ์ธ๋ฉ”๋ชจ๋ฆฌ ์บ์‹ฑ

    • Caffeine ์บ์‹œ๋ฅผ ์ด์šฉํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ ์บ์‹ฑ
      • ์‘๋‹ต ์‹œ๊ฐ„ 29% ๋‹จ์ถ•
  2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ตœ์ ํ™”

    • Skip Lock ์„ ์ด์šฉํ•œ ๋™์‹œ์„ฑ ์ œ์–ด (SELECT ... FOR UPDATE SKIP LOCKED)
      • ์‘๋‹ต ์‹œ๊ฐ„ 68% ๋‹จ์ถ• Wiki
  3. ๋น„๋™๊ธฐ ๋ฐ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ

    • CompletableFuture๋ฅผ ์ด์šฉํ•œ ๋น„๋™๊ธฐ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ
    • ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ปค์Šคํ…€ ์ธ๋ฉ”๋ชจ๋ฆฌ ํ ๊ตฌํ˜„
    • JDBC ๋ฐฐ์น˜ ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•œ ๋ฒŒํฌ ์—ฐ์‚ฐ ํšจ์œจํ™”
    • RPS 23% ํ–ฅ์ƒ Wiki
  4. ๋Œ€๊ธฐ์—ด ์‹œ์Šคํ…œ ์„ค๊ณ„

    • ํ‹ฐ์ผ“ํŒ… ์‹œ ์„œ๋น„์Šค ๊ฐ€์šฉ์„ฑ ํ™•๋ณด๋ฅผ ์œ„ํ•œ ๋Œ€๊ธฐ์—ด ์‹œ์Šคํ…œ ๋„์ž…
    • 5000๋ช… ๋™์‹œ ์ ‘์†์ž์—๋„ ๋ฉ”์ธ ์„œ๋ฒ„ CPU ์‚ฌ์šฉ๋ฅ  50% ์ดํ•˜๋กœ ์•ˆ์ •์„ฑ ํ™•๋ณด Wiki
  5. ์‹œ์Šคํ…œ ์•ˆ์ •์„ฑ ๋ฐ ๋ณต๊ตฌ ์ „๋žต

    • ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„๋ฅผ ํ™œ์šฉํ•œ ์žฌ์‹œ๋„ ๋กœ์ง ๊ตฌํ˜„
    • ์žฅ์•  ์ƒํ™ฉ ๋Œ€๋น„ ๋ณต๊ตฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๊ตฌํ˜„ (๋กœ๊ทธ ๊ธฐ๋ฐ˜ ๋ณต๊ตฌ)

๐Ÿ‘ฅ ํŒ€ ์†Œ๊ฐœ

์ €ํฌ๋Š” ํŒ€ twoDari์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์™€ ์ถ•์ œ๋ฅผ ์ด์–ด์ฃผ๋Š” ๋‹ค๋ฆฌ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฆ„ ์—ญํ•  ์ฃผ์š” ๊ธฐ์—ฌ GitHub
๊น€ํ˜„์ข… ๋ฐฑ์—”๋“œ MySQL๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ, ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ, ํ”„๋ก ํŠธ์—”๋“œ ํ™”๋ฉด ๊ตฌ์„ฑ @bellringstar
๊น€๊ทœ์› ๋ฐฑ์—”๋“œ ์บ์‹ฑ์ „๋žต, Redis๋ฅผ ์‚ฌ์šฉํ•œ ๋Œ€๊ธฐ์—ด, ํ”„๋ก ํŠธ์—”๋“œ ํ™”๋ฉด ๊ตฌ์„ฑ @kkyu0718
๊น€ํ˜„์ค€ ๋ฐฑ์—”๋“œ devops, ์Šค์ผ€์ฅด๋ง ์ž‘์—…, ๋‹ค์–‘ํ•œ ๋ชจ๋“ˆ ๊ฐ„ ์—ฐ๊ณ„ ๋ฐ ์„ฑ๋Šฅ ๊ฐœ์„  @HyeonJun0530
๋ฐ•๋ฏผ์ง€ ๋ฐฑ์—”๋“œ Redis๋ฅผ ์‚ฌ์šฉํ•œ ๋Œ€๊ธฐ์—ด ๋กœ์ง, ํ”„๋กœ์ ํŠธ ๋ชจ๋“ˆํ™” @minnim1010