๊ด€๋ฆฌ ๋ฉ”๋‰ด

Welcome! Everything is fine.

TableNow ๊ฐœ๋ฐœ ํšŒ๊ณ  #1 โ€“ API ์„ค๊ณ„, ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง, ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜์™€ ์ดˆ๊ธฐ ๊ตฌํ˜„ ๋ณธ๋ฌธ

์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

TableNow ๊ฐœ๋ฐœ ํšŒ๊ณ  #1 โ€“ API ์„ค๊ณ„, ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง, ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜์™€ ์ดˆ๊ธฐ ๊ตฌํ˜„

๊ฐœ๋ฐœ๊ณฐ๋ฐœ 2025. 4. 10.
728x90

๐Ÿฝ๏ธ์ตœ์ข… ํ”„๋กœ์ ํŠธ ์‹œ์ž‘!

๋“œ๋””์–ด ์ตœ์ข… ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ–ˆ๋‹ค. ์‚ฌ์‹ค ๋ฒŒ์จ 2์ฃผ์ฐจ๊ฐ€ ๋๋‚ฌ์ง€๋งŒ ์ •์‹ ์—†์ด ๋‹ฌ๋ ค์˜ค๋‹ค๋ณด๋‹ˆ ๋ธ”๋กœ๊ทธ์— ๊ธฐ๋ก์„ ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค.

ํ•œ ์ฃผ๊ฐ€ ๋๋‚  ๋•Œ๋งˆ๋‹ค ๊พธ์ค€ํžˆ ๊ธฐ๋กํ•˜๋Š” ์Šต๊ด€์„ ๊ฐ€์ง€์ž.โœ๐Ÿป

์šฐ๋ฆฌ ํŒ€์€ ํ…Œ์ด๋ธ”๋ง ์„œ๋น„์Šค๋ฅผ ์ฃผ์ œ๋กœ ์ •ํ–ˆ๋‹ค!

  • ํ”„๋กœ์ ํŠธ๋ช… : TableNow (ํ…Œ์ด๋ธ”๋‚˜์šฐ)
  • ์ฃผ์ œ : ์‹๋‹น์„ ์˜ˆ์•ฝํ•˜๊ณ  ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์‹œ๊ฐ„ ์˜ˆ์•ฝ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ

๐Ÿ“† 1 ~ 2์ฃผ์ฐจ ์ผ์ •

  • S.A ์ž‘์„ฑ ํ›„ ํ”ผ๋“œ๋ฐฑ ๋ฐ›๊ธฐ
  • ๊ธฐ๋ณธ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ์™„๋ฃŒ
  • ๊ธฐ๋ณธ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ํ›„ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ›๊ธฐ

ํ•ต์‹ฌ ๊ธฐ๋Šฅ

์šฐ๋ฆฌ ํŒ€์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ธ์ฆ/๋ณด์•ˆ Spring Security + JWT
Refresh Token ์ €์žฅ ๋ฐ ๊ด€๋ฆฌ(Redis)
OAuth2.0 ๋กœ๊ทธ์ธ ์—ฐ๋™
๊ฒ€์ƒ‰/์บ์‹ฑ ์ธ๊ธฐ ๊ฒ€์ƒ‰์–ด ์บ์‹ฑ(Redis)
Elasticsearch
๋™์‹œ์„ฑ ์ œ์–ด Redisson
Redis Sorted Set
MQ RabbitMQ

 

๋‚˜๋Š” ์˜ˆ์•ฝ/์ด๋ฒคํŠธ ๋„๋ฉ”์ธ์„ ๋งก์•˜๊ณ , ๋™์‹œ์„ฑ ์ œ์–ด๋Š” ์ฒ˜์Œ์ด์–ด์„œ ํ•ต์‹ฌ ๊ธฐ์ˆ ์— ๋Œ€ํ•ด ๊ณ ๋ฏผ์ด ๋งŽ์•˜๋‹ค.

๊ธฐ์ˆ ์ ์˜์‚ฌ๊ฒฐ์ • ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

Redisson (๋ถ„์‚ฐ ๋ฝ)

๐Ÿ“Œ ๋ชฉ์ : ์˜ˆ์•ฝ ๋ฐ ์ด๋ฒคํŠธ ์š”์ฒญ ์‹œ ์ค‘๋ณต ์ฒ˜๋ฆฌ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ถ„์‚ฐ ๋ฝ ๊ตฌํ˜„

[์„ ํƒ ์ด์œ ]

  • Redis ๊ธฐ๋ฐ˜์œผ๋กœ ๋น ๋ฅด๊ณ  ๊ฐ€๋ณ๊ฒŒ ๋ฝ์„ ์ œ์–ด ๊ฐ€๋Šฅ
  • Redisson์€ ๋‹ค์–‘ํ•œ ๋ฝ ํƒ€์ž… ์ง€์› (Fair, Reentrant ๋“ฑ)
  • TTL ์„ค์ •์œผ๋กœ ๋ฐ๋“œ๋ฝ ๋ฐฉ์ง€ ๊ฐ€๋Šฅ
  • Spring Boot์™€์˜ ํ†ตํ•ฉ์ด ์‰ฌ์›€

[๋‹ค๋ฅธ ๊ธฐ์ˆ ๊ณผ์˜ ๋น„๊ต]

  • DB ํŠธ๋žœ์žญ์…˜ ๋ฝ (SELECT ... FOR UPDATE): ๋‹จ์ผ DB ํ™˜๊ฒฝ์—์„œ๋Š” ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ๋Š” ์‚ฌ์šฉ ๋ถˆ๊ฐ€
  • ZooKeeper: ๊ณ ์‹ ๋ขฐ ๋ฝ์„ ์ œ๊ณตํ•˜์ง€๋งŒ ์šด์˜ ๋ณต์žก๋„๊ฐ€ ๋งค์šฐ ๋†’์Œ

[๊ฒฐ๋ก ]
๋ณต์žกํ•œ ๋ฝ ์‹œ์Šคํ…œ์„ ์“ฐ๊ธฐ๋ณด๋‹ค, Redis ๊ธฐ๋ฐ˜์˜ ๊ฐ„๋‹จํ•˜๋ฉด์„œ๋„ ์•ˆ์ •์ ์ธ ๋ฝ์˜ ํ•„์š”์„ฑ์„ ๋А๊ปด Redisson์œผ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.
๋˜ํ•œ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ๋„ Redis๋ฅผ ์ด๋ฏธ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์ถ”๊ฐ€์ ์ธ ๋ฆฌ์Šคํฌ ์—†์ด ๋„์ž…์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Redis Sorted Set - ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ํŠธ๋ฆฌ๊ฑฐ ์ฒ˜๋ฆฌ

๐Ÿ“Œ ๋ชฉ์ : ๋ฆฌ๋งˆ์ธ๋“œ ์•Œ๋ฆผ, ์ด๋ฒคํŠธ ์˜คํ”ˆ๊ณผ ๊ฐ™์ด ํŠน์ • ์‹œ๊ฐ„์— ๋ฐœ์ƒํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์„ ์Šค์ผ€์ค„๋ง

[์„ ํƒ ์ด์œ ]

  • Sorted Set์˜ score์— timestamp๋ฅผ ์‚ฌ์šฉํ•ด ์‹œ๊ฐ„์ˆœ ์ •๋ ฌ ๊ฐ€๋Šฅ
  • ์ฃผ๊ธฐ์ ์ธ polling์œผ๋กœ ์‹คํ–‰ ๋Œ€์ƒ๋งŒ ๋น ๋ฅด๊ฒŒ ์ถ”์ถœ ๊ฐ€๋Šฅ
  • ๋ฐฐ์น˜๋ณด๋‹ค ์‹ค์‹œ๊ฐ„์— ๊ฐ€๊น๊ณ , ๊ตฌํ˜„๊ณผ ์šด์˜์ด ๊ฐ„ํŽธํ•จ
  • Redis ์ธํ”„๋ผ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ๋„์ž… ๋น„์šฉ ๊ฑฐ์˜ ์—†์Œ

[๋‹ค๋ฅธ ๊ธฐ์ˆ ๊ณผ์˜ ๋น„๊ต]

  • Quartz Scheduler: ์ •๊ธฐ์ ์ธ ์ž‘์—…์„ ์ •๋ฐ€ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•จ
  • RabbitMQ Delayed Queue: ๊ตฌํ˜„ ๋ณต์žกํ•˜๊ณ  ์œ ์—ฐ์„ฑ ๋‚ฎ์Œ, ์ง€์—ฐ ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜(ex. 5๋ถ„ ๋’ค, 10๋ถ„ ๋’ค)์ด๋ผ ํŠน์ • ์‹œ๊ฐ„ ํŠธ๋ฆฌ๊ฑฐ์—๋Š” ๋ถˆํŽธํ•จ
  • ์ผ๋ฐ˜ DB + ๋ฐฐ์น˜: ์‹ค์‹œ๊ฐ„ ๋ฐ˜์‘์ด ์–ด๋ ต๊ณ  ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๊ฐ€ ๋  ์ˆ˜ ์žˆ์Œ

[๊ฒฐ๋ก ]
์‹œ๊ฐ„์„ score๋กœ ์„ค์ •ํ•˜์—ฌ ์ •ํ™•ํ•œ ์‹œ๊ฐ„์— ๋งž์ถฐ์„œ ์ž‘์—…์„ ํŠธ๋ฆฌ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ ๋ฆฌ๋งˆ์ธ๋“œ ์•Œ๋ฆผ, ์ด๋ฒคํŠธ ์˜คํ”ˆ ์‹œ๊ฐ„ ๋„๋‹ฌ ์‹œ ํŠธ๋ฆฌ๊ฑฐ(๊ฐ€๊ฒŒ ์ƒํƒœ ๋ณ€๊ฒฝ) ์ž‘์—…์— ์ ํ•ฉํ•˜๋‹ค.
๋˜ํ•œ ์ด๋ฒคํŠธ ์˜คํ”ˆ ์‹œ ์‹ค์‹œ๊ฐ„ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜์˜ Redis๊ฐ€ ํšจ์œจ์ ์ด๋‹ค.

RabbitMQ - ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ ์ „ํŒŒ

๐Ÿ“Œ ๋ชฉ์ : ์˜ˆ์•ฝ ์™„๋ฃŒ, ๋ฆฌ๋งˆ์ธ๋“œ ์•Œ๋ฆผ, ์ด๋ฒคํŠธ ์˜คํ”ˆ ์•Œ๋ฆผ์„ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์œผ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ์ „ํŒŒ

[์„ ํƒ ์ด์œ ]

  • ๋ฉ”์‹œ์ง€ ์ „์†ก์˜ ์‹ ๋ขฐ์„ฑ ๋ณด์žฅ
  • ๋น„๋™๊ธฐ ๋ฉ”์‹œ์ง• ์‹œ์Šคํ…œ์œผ๋กœ ๊ฐ ๋„๋ฉ”์ธ ๊ฐ„ ๋А์Šจํ•œ ๊ฒฐํ•ฉ ์œ ์ง€
  • ๋‹ค์–‘ํ•œ ๋ฉ”์‹œ์ง• ํŒจํ„ด (Fanout, Topic ๋“ฑ)์„ ์ œ๊ณตํ•ด ์œ ์—ฐํ•œ ๋ผ์šฐํŒ… ๊ฐ€๋Šฅ

[๋‹ค๋ฅธ ๊ธฐ์ˆ ๊ณผ์˜ ๋น„๊ต]

  • Kafka: ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ, ์‹ค์‹œ๊ฐ„, ๊ณ ์„ฑ๋Šฅ, ๊ณ ๊ฐ€์šฉ์„ฑ์„ ์ œ๊ณตํ•˜์ง€๋งŒ ๋กœ๊ทธ ๊ธฐ๋ฐ˜ ์ŠคํŠธ๋ฆฌ๋ฐ์— ์ดˆ์ , ๋ณต์žก์„ฑ ๋ฐ ์„ค์ •์ด ๊ณผ๋„ํ•จ
  • Redis Pub/Sub: ์„ค์ •์ด ๊ฐ„๋‹จํ•˜๊ณ  ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์—†์–ด ๊ฐ€๋ณ์ง€๋งŒ ๋ฉ”์‹œ์ง€ ์œ ์‹ค ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Œ
  • AWS SQS: ํด๋ผ์šฐ๋“œ ์ข…์†์ ์ด๊ณ  ๋น„์šฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ

[๊ฒฐ๋ก ]
MQ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด์ง€๋งŒ, ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋‚˜ ๋กœ๊ทธ ์ถ”์ , ์žฌ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์€ ์•„๋‹ˆ์—ˆ๋‹ค.
๋‹ค๋งŒ ๋ฆฌ๋งˆ์ธ๋“œ ์•Œ๋ฆผ๋ฟ ์•„๋‹ˆ๋ผ ๋นˆ์ž๋ฆฌ ์•Œ๋ฆผ, ์ด๋ฒคํŠธ ์˜คํ”ˆ ์•Œ๋ฆผ์ฒ˜๋Ÿผ ์„ ์ฐฉ์ˆœ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•˜๋Š” ์ด๋ฒคํŠธ๋“ค์ด ์กด์žฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—
๋ฉ”์‹œ์ง€์˜ ์ •ํ™•ํ•œ ๋„์ฐฉ ๋ณด์žฅ์ด ๋ฌด์—‡๋ณด๋‹ค ์ค‘์š”ํ–ˆ๋‹ค.
์ด์— ๋”ฐ๋ผ Kafka๋ณด๋‹ค ์†๋„๋Š” ๋А๋ฆฌ๋”๋ผ๋„, ์ •ํ™•ํ•œ ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ๊ณผ ์œ ์—ฐํ•œ ๋ผ์šฐํŒ…์ด ๊ฐ€๋Šฅํ•œ RabbitMQ๋ฅผ ์„ ํƒํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

์™€์ด์–ดํ”„๋ ˆ์ž„

API ์„ค๊ณ„

๋…ธ์…˜์œผ๋กœ ํŒ€์›๋“ค๊ณผ ์ž‘์„ฑํ•œ API ๋ช…์„ธ์„œ๋‹ค. ๋ถ„๋ฅ˜, ๋‹ด๋‹น์ž, ์ง„ํ–‰์‚ฌํ•ญ, ๋ฉ”์„œ๋“œ, ๊ธฐ๋Šฅ, URI, ์‘๋‹ต/์š”์ฒญ ํ—ค๋” ๋ฐ ๋ฐ”๋””, ์ƒํƒœ ์ฝ”๋“œ ๋“ฑ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. RESTfulํ•œ API๋ฅผ ์„ค๊ณ„ํ•˜๊ณ ์ž ํ–ˆ๋‹ค.

๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง

์ดˆ๊ธฐ ERD๋Š” ๋ฆฌ๋ทฐ, ๋Œ“๊ธ€, ์ข‹์•„์š”, ์ฆ๊ฒจ์ฐพ๊ธฐ ๋“ฑ ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์ด ๋งŽ์•˜๋‹ค. ํ•˜์ง€๋งŒ ๋น„์ฆˆ๋‹ˆ์Šค์ ์œผ๋กœ ๋‹ค๊ฐ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ๊ธฐ์ˆ ์ ์ธ ๋„์ „์„ ํ•˜๋Š” ๊ฒƒ์— ์ดˆ์ ์„ ๋งž์ถ”๊ธฐ๋กœ ํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ…Œ์ด๋ธ” ์ˆ˜๋ฅผ ์ค„์ด๊ณ  ๊ฐ์ž ํ•ต์‹ฌ์ ์ธ 1 ~ 2๊ฐœ์˜ ๋„๋ฉ”์ธ๋งŒ ๋งก์•„ ์ง„ํ–‰ํ–ˆ๋‹ค.

 

์•„๋งˆ ๊ธฐ์ˆ  ๊ณ ๋„ํ™”๊ฐ€ ์ง„ํ–‰๋˜๋ฉด ์ข€ ๋” ์ˆ˜์ •๋  ๊ฒƒ์ด๋‹ค.

์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„

์šฐ๋ฆฌ ํŒ€์€ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ๋ฐฉ์‹์„ ์›ํ–ˆ๋Š”๋ฐ, ํ˜„์‹ค์ ์ธ ์ƒํ™ฉ์— ๋งž์ถฐ EC2 1๋Œ€์— ์ปจํ…Œ์ด๋„ˆ 2๊ฐœ๋ฅผ ๋„์šฐ๊ณ  ๊ทธ ์•ž๋‹จ์— Nginx์™€ ๊ฐ™์€ ์›น์„œ๋ฒ„๋ฅผ ๋‘๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ •ํ–ˆ๋‹ค. Blue-Green ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ•˜๊ณ ์ž ํ•œ๋‹ค.

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

table-now
โ”œโ”€โ”€ .github
โ”‚   โ””โ”€โ”€ ISSUE_TEMPLATE
โ”‚       โ”œโ”€โ”€ feature-request-issue-template.md
โ”‚       โ””โ”€โ”€ PULL_REQUEST_TEMPLATE.md
โ”œโ”€โ”€ src
โ”‚   โ”œโ”€โ”€ main
โ”‚   โ”‚   โ”œโ”€โ”€ java
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ org.example.tablenow
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ domain
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ auth
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ category
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ event
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ image
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ notification
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ payment
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ reservation
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ store
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ user
โ”‚   โ”‚   โ”‚       โ”‚   โ””โ”€โ”€ waitlist
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ global
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ annotation
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ config
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ dto
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ entity
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ exception
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ filter
โ”‚   โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ security
โ”‚   โ”‚   โ”‚       โ”‚   โ””โ”€โ”€ util
โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ TableNowApplication.java
โ”‚   โ”‚   โ””โ”€โ”€ resources
โ”‚   โ”‚       โ”œโ”€โ”€ application.yml
โ”‚   โ”‚       โ”œโ”€โ”€ application-local.yml
โ”‚   โ”‚       โ””โ”€โ”€ application-test.yml
โ”‚   โ””โ”€โ”€ test
โ”œโ”€โ”€ Dockerfile
โ”œโ”€โ”€ docker-compose.yml
โ”œโ”€โ”€ .env
โ”œโ”€โ”€ .env.local
โ”œโ”€โ”€ .env.test
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ .gitattributes
โ”œโ”€โ”€ build.gradle
โ”œโ”€โ”€ gradlew
โ”œโ”€โ”€ gradlew.bat
โ”œโ”€โ”€ settings.gradle

 

๐Ÿค” ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ด€๋ฆฌ๋Š” ์–ด๋–ป๊ฒŒ ํ• ๊นŒ?
์šฐ๋ฆฌ๋Š” ํ™˜๊ฒฝ๋งˆ๋‹ค ๋‹ค๋ฅธ ์„ค์ •์„ ์œ ์—ฐํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด,
Spring Boot์˜ application.yml ๊ณ„์ธต ๊ตฌ์กฐ์™€ .env ํŒŒ์ผ์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์„ ์„ ํƒํ–ˆ๋‹ค.

  • application.yml : ๊ณตํ†ต ์„ค์ •
  • application-local.yml : ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •
  • application-test.yml : ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ์„ค์ •

์ด ์„ค์ • ํŒŒ์ผ๋“ค๊ณผ ์—ฐ๋™๋˜๋Š” .env.env.local.env.test ํŒŒ์ผ์„ ๊ฐ๊ฐ ๋งŒ๋“ค์–ด
DB ์ ‘์† ์ •๋ณด, Redis ์„ค์ •, AWS ์ž๊ฒฉ ์ฆ๋ช… ๋“ฑ ์™ธ๋ถ€ ๋…ธ์ถœ๋˜๋ฉด ์•ˆ ๋˜๋Š” ๋ฏผ๊ฐํ•œ ๊ฐ’์„ ์—ฌ๊ธฐ์— ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•ด ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด .env.local์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฐ’๋“ค์ด ๋“ค์–ด๊ฐ„๋‹ค.

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” Git์— ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๊ณ ,
๊ฐ ํ™˜๊ฒฝ๋ณ„๋กœ .env๋งŒ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋ฐ”๋กœ ์„ค์ •์ด ์ ์šฉ๋˜์–ด ํ›จ์”ฌ ์•ˆ์ „ํ•˜๊ณ  ํŽธํ•˜๋‹ค.

 

๐Ÿ’ก EnvFile ํ”Œ๋Ÿฌ๊ทธ์ธ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ
EnvFile ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด Run/Debug Configuration์— .env ํŒŒ์ผ์„ ์‰ฝ๊ฒŒ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์•„๋ž˜์ฒ˜๋Ÿผ Run ์„ค์ •์—์„œ "Enable EnvFile" ์˜ต์…˜์„ ์ฒดํฌํ•˜๊ณ  ์›ํ•˜๋Š” .env ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด์ฃผ๋ฉด, ์‹คํ–‰ ์‹œ ํ•ด๋‹น ํ™˜๊ฒฝ๋ณ€์ˆ˜๋“ค์ด ์ž๋™์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ฃผ์ž…๋œ๋‹ค.

๊ธฐ๋Šฅ ๊ตฌํ˜„

2์ฃผ์ฐจ๋Š” ๊ธฐ์ˆ  ๊ณ ๋„ํ™”๋ฅผ ์œ„ํ•œ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๊ณ , ๊ฐ์ž ๋ฐ›์€ ์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฆฌํŒฉํ† ๋ง์„ ์ง„ํ–‰ํ–ˆ๋‹ค.

  • ์˜ˆ์•ฝ ์ƒ์„ฑ, ์กฐํšŒ, ์ˆ˜์ •, ์ทจ์†Œ, ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • ์ด๋ฒคํŠธ ๋“ฑ๋ก, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œ, ์‹ ์ฒญ(์ฐธ์—ฌ) ๊ธฐ๋Šฅ ๊ตฌํ˜„

๊ตฌํ˜„ํ•œ ๋ถ€๋ถ„์„ ์ผ์ผ์ด ์ ๊ธฐ์—” ์–‘์ด ๋งŽ๊ณ  ๊ธฐ๋ณธ์ ์ธ ์ฝ”๋“œ๋งŒ ์žˆ์–ด์„œ ๋‚ด๊ฐ€ ์‹ ๊ฒฝ ์“ด ๋ถ€๋ถ„, ๋ฆฌํŒฉํ† ๋ง ํ•œ ๋ถ€๋ถ„, ๊ณ ๋ฏผํ–ˆ๋˜ ์  ๋“ฑ์„ ๊ฐ„๋‹จํžˆ ์ ์–ด๋ณธ๋‹ค.

๊ฒ€์ฆ ์ฑ…์ž„ ๋ถ„๋ฆฌ

์˜ˆ์•ฝ ๊ธฐ๋Šฅ์—์„œ๋Š” ์˜ˆ์•ฝ ๊ฐ€๋Šฅ ์—ฌ๋ถ€, ์ค‘๋ณต ์—ฌ๋ถ€, ๋งค์žฅ ์ƒํƒœ ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ์กฐ๊ฑด์„ ๊ฒ€์ฆํ•ด์•ผ ํ–ˆ๋‹ค. ์กฐ๊ฑด์ด ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ์ฝ”๋“œ๊ฐ€ ๋น„๋Œ€ํ•ด์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ฒ€์ฆ ์ฑ…์ž„์„ ๋ฉ”์„œ๋“œ ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ํด๋ฆฐ ์ฝ”๋“œ ์›์น™(๋‹จ์ผ ์ฑ…์ž„, ๊ฐ€๋…์„ฑ, ์œ ์ง€๋ณด์ˆ˜์„ฑ)์„ ๊ณ ๋ คํ•ด ์„ค๊ณ„ํ–ˆ๋‹ค. ์ด ๋ถ€๋ถ„์€ ํŠœํ„ฐ๋‹˜๊ป˜์„œ๋„ ์ž˜ ๊ตฌ์„ฑํ–ˆ๋‹ค๊ณ  ๊ธ์ •์ ์ธ ํ”ผ๋“œ๋ฐฑ์„ ์ฃผ์…จ๋‹ค.

 

์•„๋ž˜๋Š” ์‹ค์ œ๋กœ ๋ถ„๋ฆฌํ•œ ๊ฒ€์ฆ ๋ฉ”์„œ๋“œ๋“ค์ด๋‹ค.

 

์ด๋ ‡๊ฒŒ ๋ถ„๋ฆฌํ•œ ๊ฒ€์ฆ ๋กœ์ง์€ ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์˜ˆ์•ฝ ์ƒ์„ฑ ์ „ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ๋ช…ํ™•ํžˆ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

๋„๋ฉ”์ธ์ด ์ฑ…์ž„์ง€๋Š” ์˜ˆ์•ฝ ๋ณ€๊ฒฝ ๋กœ์ง

์˜ˆ์•ฝ ์ƒํƒœ ๋ณ€๊ฒฝ ๋กœ์ง์€ ๋‹จ์ˆœํžˆ ์„œ๋น„์Šค ๋ ˆ์ด์–ด์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์˜ˆ์•ฝ ๋„๋ฉ”์ธ ์ž์ฒด๊ฐ€ ๊ทธ ์ฑ…์ž„์„ ๊ฐ€์ง€๋„๋ก ๊ตฌ์„ฑํ–ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด tryCancel() ๋ฉ”์„œ๋“œ๋Š” ๋‹จ์ˆœํ•œ setter๊ฐ€ ์•„๋‹ˆ๋ผ, ์˜ˆ์•ฝ์ด ์ทจ์†Œ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ธ์ง€ ์ž์ฒด ๊ฒ€์ฆ์„ ํฌํ•จํ•œ ๋ช…ํ™•ํ•œ ๋„๋ฉ”์ธ ํ–‰์œ„๋กœ ์ •์˜๋˜์–ด ์žˆ๋‹ค.

 

๋˜ํ•œ ๋ฉ”์„œ๋“œ ๋„ค์ด๋ฐ๋„ tryCancel, updateStatus์ฒ˜๋Ÿผ ์˜๋„๋ฅผ ์ž˜ ๋“œ๋Ÿฌ๋‚ด๋Š” ์ด๋ฆ„์œผ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ์‚ฌ๋žŒ๋„ ๋„๋ฉ”์ธ ํ๋ฆ„์„ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค.

 

์„œ๋น„์Šค ๋ ˆ์ด์–ด์—์„œ๋Š” ๋‹จ์ˆœํžˆ ํ•ด๋‹น ๋„๋ฉ”์ธ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ์กฐ๋กœ, ์ฑ…์ž„์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋‚˜๋‰œ๋‹ค.

 

์„œ๋น„์Šค ๋กœ์ง์—์„œ ์ง์ ‘ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋Œ€์‹ , ๋„๋ฉ”์ธ ๊ฐ์ฒด์—๊ฒŒ ๊ทธ ์ฑ…์ž„์„ ์œ„์ž„ํ•จ์œผ๋กœ์จ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋”์šฑ ๋ช…ํ™•ํ•˜๊ณ  ๊ฒฌ๊ณ ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋ฌผ๋ก  ์ด๋Ÿฐ ๋ฐฉ์‹์ด ๋ชจ๋“  ์ƒํ™ฉ์— ์ •๋‹ต์€ ์•„๋‹ˆ์ง€๋งŒ, ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ž˜ ํŒ๋‹จํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

์˜ˆ์•ฝ ์‹œ๊ฐ„ ๊ฒ€์ฆ ๋ฆฌํŒฉํ† ๋ง

์ดˆ๊ธฐ์—๋Š” ์˜ˆ์•ฝ ์‹œ๊ฐ„์˜ ์œ ํšจ์„ฑ์„ ์„œ๋น„์Šค๋‹จ์—์„œ ๋ฉ”์„œ๋“œ๋กœ ์ง์ ‘ ๊ฒ€์ฆํ–ˆ๋‹ค.
์•„๋ž˜์™€ ๊ฐ™์ด validateReservedAtHalfHour() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ •์‹œ(00๋ถ„) ๋˜๋Š” 30๋ถ„ ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋ฐฉ์‹์ด์—ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ํŠœํ„ฐ๋‹˜์œผ๋กœ๋ถ€ํ„ฐ "์š”์ฒญ DTO์˜ ๋‹จ์ผ ํ•„๋“œ ์œ ํšจ์„ฑ์€ ์ปจํŠธ๋กค๋Ÿฌ ๋‹จ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•˜๋‹ค" ๋Š” ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ณ , ํ•ด๋‹น ๊ฒ€์ฆ ์ฑ…์ž„์„ ์š”์ฒญ ๊ฐ์ฒด ์ชฝ์œผ๋กœ ์ด๋™ํ–ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํŒ€์› ๋ถ„์ด ํ•˜์‹  ๋ฐฉ์‹์„ ๋”ฐ๋ผ ์ปค์Šคํ…€ ์–ด๋…ธํ…Œ์ด์…˜ @HalfHourOnly๋ฅผ ์ด์šฉํ•ด ์ปจํŠธ๋กค๋Ÿฌ ์ง„์ž… ์‹œ์ ์—์„œ ์ž…๋ ฅ๊ฐ’์˜ ํ˜•์‹์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฆฌํŒฉํ† ๋งํ–ˆ๋‹ค.

 

๊ฒ€์ฆ ๋กœ์ง์„ ์ปจํŠธ๋กค๋Ÿฌ ๋‹จ์œผ๋กœ ์ด๋™์‹œํ‚ด์œผ๋กœ์จ ์„œ๋น„์Šค ๋‹จ์˜ ์ฑ…์ž„์„ ๋ช…ํ™•ํžˆ ํ•˜๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ํ๋ฆ„์„ ๋” ๊น”๋”ํ•˜๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

DB Lock ๊ตฌํ˜„

์ฒ˜์Œ์—๋Š” ์ •๋ง ๊ธฐ๋ณธ ๊ธฐ๋Šฅ๋งŒ ๊ตฌํ˜„ํ•œ ํ›„ Redisson์„ ์ ์šฉํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ, ๋ง‰์ƒ ์ง„ํ–‰ํ•˜๋ ค๋‹ˆ ์•„์ฃผ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ์—ฌ์„œ ๋ฒ ์ด์Šค ๋ผ์ธ์œผ๋กœ ํ•˜๊ธฐ์—๋Š” ๋ถ€์‹คํ•œ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ ํŠœํ„ฐ๋‹˜๊ป˜ ์งˆ๋ฌธํ•˜๋‹ˆ "ํ˜„์žฌ ์ƒํ™ฉ๊ณผ Redisson ๋ฝ ์ ์šฉ์„ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์€ ํฌ๊ฒŒ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค" ๋ผ๊ณ  ํ•˜์…จ๋‹ค. ๋”ฐ๋ผ์„œ ์ถ”ํ›„ ๋น„๊ต๋ฅผ ํ•œ๋‹ค๋ฉด DB ๋ฝ vs Redisson ๋ถ„์‚ฐ ๋ฝ์„ ํ•ด๋ณด๋Š” ๊ฒƒ์ด ๋” ๋‚ซ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์šฐ์„ ์€ DB ๋ฝ์„ ๋จผ์ € ์ ์šฉํ•ด๋ณด๊ธฐ๋กœ ํ•˜๊ณ , JMeter๋„ ์ตํž ๊ฒธ v1๊ณผ v2๋ฅผ ๋‚˜๋ˆ  ์ง„ํ–‰ํ–ˆ๋‹ค.

  • v1 : ๋ณ„๋„์˜ ๋ฝ ์—†์ด ๊ธฐ๋ณธ ๋กœ์ง ๊ตฌํ˜„
  • v2 : Pessimistic Lock(DB ๋ฝ)์„ ์ ์šฉํ•ด ์ค‘๋ณต ์ฐธ์—ฌ ๋ฐฉ์ง€ ๋ฐ ์ •ํ•ฉ์„ฑ ํ™•๋ณด

์ฝ”๋“œ ์ž์ฒด๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์ œ์™ธํ•˜๊ณ ๋Š” ๋ชจ๋‘ ๋™์ผํ•˜๋‹ค. v2์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋น„๊ด€์  ๋ฝ์ด ์ ์šฉ๋œ findByIdForUpdate() ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ์ด๋ฒคํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

 

์ •์›์ด 10๋ช…์ธ ์ด๋ฒคํŠธ์— 200๋ช…์ด ๋™์‹œ์— ์ด๋ฒคํŠธ๋ฅผ ์‹ ์ฒญํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋‹ˆ, ๊ทธ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•˜๋‹ค.

No Lock(์™ผ) / DB Lock(์˜ค)
No Lock(์™ผ) / DB Lock(์˜ค)

 

์ •๋ฆฌํ•ด๋ณด๋ฉด, No Lock ๋ฒ„์ „์€ ์‘๋‹ต ์†๋„๋Š” ๋น ๋ฅด์ง€๋งŒ ์ดˆ๊ณผ ์‹ ์ฒญ์ด ๋ฐœ์ƒํ•ด ์ •ํ•ฉ์„ฑ์ด ๊นจ์กŒ๋‹ค. 

๋ฐ˜๋ฉด, DB Lock์„ ์ ์šฉํ•œ ๋ฒ„์ „์€ ์‘๋‹ต ์‹œ๊ฐ„๊ณผ ์ฒ˜๋ฆฌ๋Ÿ‰์€ ๊ฐ์†Œํ–ˆ์ง€๋งŒ, ์ •ํ™•ํžˆ 10๋ช…๋งŒ ์‹ ์ฒญ๋˜๋ฉฐ ์ •ํ•ฉ์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

Redisson ๊ธฐ๋ฐ˜ ๋ถ„์‚ฐ ๋ฝ(v3) ์ ์šฉ ์‹œ์—๋Š” ์ด ๋‘ ๊ฐ€์ง€ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ณ ๋„ํ™”๋ฅผ ์ง„ํ–‰ํ•  ์˜ˆ์ •์ด๋‹ค.

ํ•ญ๋ชฉ No Lock DB Lock
์š”์ฒญ ์ˆ˜ 200 200
ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„ 53ms ๐ŸŸข 415ms ๐Ÿ”ด
์ตœ๋Œ€ ์‘๋‹ต ์‹œ๊ฐ„ 199ms 753ms
์—๋Ÿฌ์œจ 90.50% 95.00%
Throughput 507.6/sec ๐ŸŸข 233.9/sec
์ „์†ก/์ˆ˜์‹  KB/sec 208.22 / 109.06 94.20 / 50.26

ํ…Œ์ŠคํŠธ

ํ˜„์žฌ๋Š” DB ๋ฝ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฒคํŠธ ์‹ ์ฒญ API์˜ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, JMeter๋ฅผ ํ™œ์šฉํ•ด ์ •ํ•ฉ์„ฑ ์ค‘์‹ฌ์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ–ˆ๋‹ค.
๋‹จ์ผ ์š”์ฒญ ๊ธฐ์ค€์˜ API๋Š” Postman์œผ๋กœ ์ถฉ๋ถ„ํ–ˆ์ง€๋งŒ, ์ด๋ฒคํŠธ์™€ ๊ฐ™์ด ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด์„œ๋Š”
๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ถฉ๋Œ์ด ์—†๋Š”์ง€ ์ค‘์ ์ ์œผ๋กœ ๊ฒ€์ฆํ–ˆ๋‹ค.
์ดํ›„ Redisson ์ ์šฉ ์‹œ, ๋™์ผํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ์„ฑ๋Šฅ ๋ฐ ์•ˆ์ •์„ฑ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณผ ์˜ˆ์ •์ด๋‹ค.

Postman

  • ์ฃผ์š” ์šฉ๋„: REST API ๊ธฐ๋ณธ ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ ๋ฐ ๋น ๋ฅธ ๊ฒ€์ฆ
  • ํ™œ์šฉ ๋‚ด์šฉ
    • ์ธ์ฆ, ํšŒ์›๊ฐ€์ž…, ์˜ˆ์•ฝ, ์ด๋ฒคํŠธ ๋“ฑ API์˜ ์ •์ƒ ์‘๋‹ต/์—๋Ÿฌ ์‘๋‹ต ํ™•์ธ
    • ๋‹ค์–‘ํ•œ ์š”์ฒญ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •์„ ํ†ตํ•ด ๋ฐ˜๋ณต ์‹คํ–‰
    • ํŒ€์› ๊ฐ„ ๊ณต์œ ๋ฅผ ์œ„ํ•ด ํ…Œ์ŠคํŠธ ์ปฌ๋ ‰์…˜ ๊ตฌ์„ฑ ๋ฐ ๋ฌธ์„œํ™”

JMeter

  • ์ฃผ์š” ์šฉ๋„: ์ด๋ฒคํŠธ ์‹ ์ฒญ API ๋“ฑ ๋™์‹œ์„ฑ ๋ฌธ์ œ ๋ฐœ์ƒ ๊ฐ€๋Šฅ ๊ตฌ๊ฐ„์˜ ์ •ํ•ฉ์„ฑ ํ…Œ์ŠคํŠธ, ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ
  • ํ™œ์šฉ ๋‚ด์šฉ
    • ํ˜„์žฌ๋Š” DB ๋ฝ(Pessimistic Lock)์„ ์ ์šฉํ•œ ์ƒํƒœ
    • ์ด๋ฒคํŠธ ์‹ ์ฒญ ์‹œ ์ค‘๋ณต ์ฐธ์—ฌ๋‚˜ ์ดˆ๊ณผ ์‹ ์ฒญ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธ
    • ๋‹ค์–‘ํ•œ ์Šค๋ ˆ๋“œ ์ˆ˜๋กœ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋ฉฐ ์ •ํ•ฉ์„ฑ ์œ ์ง€ ์—ฌ๋ถ€ ์ฒดํฌ
  • ์„ฑ๋Šฅ๋ณด๋‹ค ๋ฐ์ดํ„ฐ ์ถฉ๋Œ ๋ฐฉ์ง€ ๋ฐ ๋™์‹œ ์š”์ฒญ ์‹œ ์•ˆ์ •์„ฑ ํ™•์ธ์ด ๋ชฉ์ 
  • ํ–ฅํ›„ Redisson ๋ถ„์‚ฐ ๋ฝ ์ „ํ™˜ ์ „ ๋น„๊ต ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๊ธฐ๋ฐ˜ ๋งˆ๋ จ