Skip to content

Latest commit

ย 

History

673 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ  ๋ฐฉ์ค˜ : ์ค‘๊ฐœ์‚ฌ ์—†์ด ์‹ธ๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ

๋ธ”๋ก์ฒด์ธ ๊ธฐ๋ฐ˜ ์›์Šคํ†ฑ ๋ถ€๋™์‚ฐ ๊ฑฐ๋ž˜ ํ”Œ๋žซํผ


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

**"๋ฐฉ์ค˜"**๋Š” ๋ถ€๋™์‚ฐ ์ค‘๊ฐœ ์ˆ˜์ˆ˜๋ฃŒ์™€ ์‚ฌ๊ธฐ ์œ„ํ—˜์„ ์ค„์ด๊ธฐ ์œ„ํ•ด
AI์™€ ๋ธ”๋ก์ฒด์ธ์„ ๊ฒฐํ•ฉํ•˜์—ฌ ๋งŒ๋“  ๋ถ€๋™์‚ฐ ๊ฑฐ๋ž˜ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.

  • ๋งž์ถคํ˜• ๋งค๋ฌผ ํƒ์ƒ‰๋ถ€ํ„ฐ ๊ณ„์•ฝ ์ฒด๊ฒฐ๊นŒ์ง€ ํ•œ ๋ฒˆ์—!
  • ๊ณ„์•ฝ์„œ ์ž‘์„ฑ์ด ์–ด๋ ค์šธ ๋• AI ์ฑ—๋ด‡์ด ๋„์™€๋“œ๋ฆฝ๋‹ˆ๋‹ค.
  • ๊ณ„์•ฝ์€ ๋ธ”๋ก์ฒด์ธ์— ๊ธฐ๋ก๋˜์–ด ์œ„๋ณ€์กฐ ๊ฑฑ์ • ์—†์ด ํˆฌ๋ช…ํ•˜๊ฒŒ!

์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜์ฒ˜

Architecture Diagram


โš™๏ธ ๊ธฐ์ˆ  ์Šคํƒ

๋ถ„์•ผ ๊ธฐ์ˆ 
Frontend React, Typescript, TailwindCSS, TanStack Query
Backend Spring Boot, Spring Data JPA
Database MySQL, Redis, MongoDB, AWS S3
Infrastructure AWS EC2, Docker, Nginx
Blockchain Remix, Truffle, Solidity, Web3.0
AI OpenAI API (GPT ๊ธฐ๋ฐ˜ ์ฑ—๋ด‡)

์š”๊ตฌ์‚ฌํ•ญ ๋ช…์„ธ์„œ

Requirement Statement

API ๋ช…์„ธ์„œ

API Statement

โœจ ์ฃผ์š” ๊ธฐ๋Šฅ

  1. ๋งž์ถคํ˜• ๋ถ€๋™์‚ฐ ๋งค๋ฌผ ํƒ์ƒ‰

    • ์‚ฌ์šฉ์ž์˜ ์กฐ๊ฑด ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ๋ง (์œ„์น˜, ๊ฐ€๊ฒฉ, ๊ตฌ์กฐ ๋“ฑ)
    • ์ฆ‰์‹œ ํ™•์ธ ๊ฐ€๋Šฅํ•œ ๋งค๋ฌผ ์นด๋“œ ๋ทฐ ์ œ๊ณต
  2. AI ๊ธฐ๋ฐ˜ ์Šค๋งˆํŠธ ๊ณ„์•ฝ์„œ ์ง€์›

    • ๊ณ„์•ฝ์„œ ํ•ญ๋ชฉ ์‹ค์‹œ๊ฐ„ ์„ค๋ช…
    • ๋ฒ•๋ฅ  ์šฉ์–ด ๋ฐ ํŠน์•ฝ ์กฐ๊ฑด ์ดํ•ด ๋ณด์กฐ
  3. ๋ธ”๋ก์ฒด์ธ ๊ธฐ๋ฐ˜ ๊ณ„์•ฝ์„œ ๊ด€๋ฆฌ

    • IPFS ๋ฐ ๋ธ”๋ก์ฒด์ธ ๊ธฐ๋ก์œผ๋กœ ์œ„๋ณ€์กฐ ๋ฐฉ์ง€
    • ํˆฌ๋ช…ํ•˜๊ณ  ์‹ ๋ขฐ์„ฑ ์žˆ๋Š” ๊ฑฐ๋ž˜ ์ œ๊ณต
  4. ๋“ฑ๊ธฐ๋ถ€ ๊ธฐ๋ฐ˜ ์‚ฌ๊ธฐ ์˜ˆ๋ฐฉ ์‹œ์Šคํ…œ

    • ๋“ฑ๊ธฐ๋ถ€๋“ฑ๋ณธ ์ž๋™ ํŒ๋… ๋ฐ ์œ„ํ—˜๋„ ๋ถ„์„
    • ์‚ฌ๊ธฐ ์œ„ํ—˜ ๋งค๋ฌผ ์‚ฌ์ „ ๊ฒฝ๊ณ  ์ œ๊ณต
  5. ๊ณ„์•ฝ์„œ ์ž‘์„ฑ ๋ณด์กฐ ์‹œ์Šคํ…œ

    • ์ฑ—๋ด‡ ์—ฐ๋™์„ ํ†ตํ•œ ์šฉ์–ด/์กฐํ•ญ ์‹ค์‹œ๊ฐ„ ์„ค๋ช…
    • ์‚ฌ์šฉ์ž ์ค‘์‹ฌ์˜ ์ง๊ด€์  ๊ณ„์•ฝ์„œ ์ž‘์„ฑ ํ™˜๊ฒฝ

Figma

Figma Design Figma Design 2 Figma Design 3


ERD

ERD Diagram


๐Ÿ™‹ ํŒ€์› ์†Œ๊ฐœ

์ด๋ฆ„ ์—ญํ•  ๋‹ด๋‹น
๊น€๋ฒ”์ค€ PM, Backend, Infra ์ผ์ •๊ด€๋ฆฌ, ์ฑ„ํŒ…/ํฌํŠธ์›, ์„œ๋ฒ„
๊ฐ•ํ˜„์ง€ Frontend ๊ณ„์•ฝ์„œ/์ฑ„ํŒ…/์ฑ—๋ด‡, ์˜์ƒ ์ œ์ž‘
๋ฐฑ์ง€๋ฏผ Frontend ๋ฉ”์ธํŽ˜์ด์ง€/๋งค๋ฌผ/ํšŒ์›/Info
๊ฐ•๋ณด์˜ AI OpenAI ์ฑ—๋ด‡ ์‹œ์Šคํ…œ
ํ•˜์ •์ˆ˜ Backend, BlockChain ๋ธ”๋ก์ฒด์ธ, ๊ณ„์•ฝ/์•”ํ˜ธํ™”
ํ™ฉ์ธ์ค€ Backend ํ™˜๊ฒฝ์„ค์ •, ๋งค๋ฌผ/ํšŒ์›/๋กœ๊ทธ์ธ

์„œ๋ฒ„ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

1. ๊ณตํ†ต ๋ชจ๋“ˆ ๋ถ„๋ฆฌ

์ด์Šˆ ๋ฐœ์ƒ ํ™˜๊ฒฝ

  • ํŒ€์›๋งˆ๋‹ค ๋„๋ฉ”์ธ์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์žˆ์–ด ์ผ๊ด€๋˜๊ณ  ๋ช…ํ™•ํ•œ ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • JPA๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Page ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ ์ผ๊ด€๋œ ํŽ˜์ด์ง€ ํ•„ํ„ฐ๋ง ์กฐ๊ฑด๊ณผ ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์œ ์ € ํ”„๋กœํ•„ ์ด๋ฏธ์ง€, ๋งค๋ฌผ ์ด๋ฏธ์ง€, ๊ณ„์•ฝ ์„œ๋ช…, ๋“ฑ๊ธฐ๋ถ€๋“ฑ๋ณธ PDF ๋“ฑ ๋‹ค์–‘ํ•œ ๋„๋ฉ”์ธ์—์„œ AWS S3์— ํŒŒ์ผ์„ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์กฐํšŒ๊ฐ€ ํ•„์š”ํ•˜์—ฌ ์ค‘๋ณต๋œ ์ฝ”๋“œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • API ๋งˆ๋‹ค ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ API๊ฐ€ ์žˆ๊ณ  ํ•„์š”์—†๋Š” API๊ฐ€ ์กด์žฌํ•˜๊ณ , ์ถ”๊ฐ€์ ์œผ๋กœ ์ฐœ ๋งค๋ฌผ ์—ฌ๋ถ€ ๊ฐ™์€ ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ์žˆ๋‹ค๋ฉด ์ถ”๊ฐ€์ ์ธ ๋กœ์ง์ด ํ•„์š”ํ•œ API๋“ค์ด ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์Šˆ ํ•ด๊ฒฐ ๊ณ ๋ฏผ ๋ฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  • ์ผ๊ด€๋œ ์ƒํƒœ์ฝ”๋“œ, ์„œ๋ฒ„ ์˜ˆ์™ธ ์ฝ”๋“œ, ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€ ๋“ฑ์„ ๋ณด์œ ํ•œ ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•˜๊ณ , ๋„๋ฉ”์ธ๋งˆ๋‹ค ๊ด€๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„๋ฉ”์ธ ๋ณ„ ์˜ˆ์™ธ ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๋„๋ก ์„ค๊ณ„๊ฐ€ ํ•„์š”ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด์— ์žˆ์–ด ์ƒํƒœ์ฝ”๋“œ, ์„œ๋ฒ„ ์˜ˆ์™ธ ์ฝ”๋“œ, ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€ ๋“ฑ์„ ์กฐํšŒํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋„๋ฉ”์ธ ๋งˆ๋‹ค ์ƒ์†ํ•œ ENUM ์˜ˆ์™ธ ๊ตฌํ˜„์ฒด๋ฅผ ์ƒ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ€์ง€๋Š” ์ปค์Šคํ…€ ์˜ˆ์™ธ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ „์—ญ์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ๊ด€๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • JPA ์—์„œ๋Š” Page๊ฐ์ฒด๋ฅผ ์ง€์›ํ•˜์—ฌ ์—”ํ‹ฐํ‹ฐ๋“ค์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋Š”๋ฐ, Pageable๊ฐ์ฒด๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ๊ฐœ์ˆ˜์˜ ํŽ˜์ด์ง€ ์กฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์— Util ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•œ Page ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ํ•˜๋‚˜์˜ ๋„๋ฉ”์ธ์—์„œ ๋งค๋ฒˆ AWS S3 ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ๊ตฌ์กฐ๊ฐ€ ์ž˜๋ชป๋œ ์„ค๊ณ„๋กœ ํŒ๋‹จ๋˜์–ด ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ดํ›„ ๊ฐ ๋„๋ฉ”์ธ ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ์–ด๋Œ‘ํ„ฐ ํด๋ž˜์Šค๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž…ํ•˜์—ฌ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ ์‰ฝ๊ฒŒ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ์šฐ์„  ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ API์— ์žˆ์–ด ํ‘œํ˜„ ๊ณ„์ธต์—์„œ ์ปค์Šคํ…€ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•˜๊ณ , ArgumentResolver์—์„œ JWT๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  ์œ ์ € ID๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์•„์ง ์ฐœ ๋งค๋ฌผ ์กฐํšŒ ๊ฐ™์€ ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ์žˆ๋‹ค๋ฉด ์ถ”๊ฐ€์ ์œผ๋กœ ๋กœ์ง์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌํ–ˆ๊ณ , ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ปค์Šคํ…€ ์–ด๋…ธํ…Œ์ด์…˜ ๋‚ด๋ถ€์— Boolean๊ฐ’์˜ ๋ณ€์ˆ˜ ๊ด€๋ฆฌ๋ฅผ ํ†ตํ•ด ๊ธฐ๋ณธ๊ฐ’์ด ์•„๋‹ˆ๋ผ๋ฉด null์ธ ์œ ์ € ID๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฐœ์„ ๋œ ์‚ฌํ•ญ

  • ๋„๋ฉ”์ธ ๋งˆ๋‹ค ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์šฉ์ดํ•ด์กŒ๊ณ , ํด๋ผ์ด์–ธํŠธ๋Š” ์ผ๊ด€๋œ ํ˜•์‹์˜ ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐ„๋‹จํ•˜๊ฒŒ Page ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , JPA ๋‚ด๋ถ€์ ์œผ๋กœ ํ•„์š”ํ•œ ๊ฐœ์ˆ˜์˜ ์—”ํ‹ฐํ‹ฐ๋งŒ์„ ์กฐํšŒํ•˜์—ฌ ์„ฑ๋Šฅ์ด ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • AWS S3 ์ •๋ณด๋ฅผ ๋„๋ฉ”์ธ๋งˆ๋‹ค ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ณ  ํŠน์ • ์–ด๋Œ‘ํ„ฐ ํด๋ž˜์Šค๊ฐ€ ๊ด€๋ฆฌํ•˜์—ฌ ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด ์‚ฌ์šฉ์ด ์šฉ์ดํ•ด์ง€๊ณ , ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๊ฐ์†Œํ•˜๋Š” ๋“ฑ ๋” ๊ฐ์ฒด ์ง€ํ–ฅ์ ์ธ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ API๋ฅผ ๊ฐœ๋ฐœ์ž๋“ค์ด ํ•œ๋ˆˆ์— ๋ณด๊ธฐ ์šฉ์ดํ•ด์กŒ๊ณ , ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ํŒŒ์‹ฑํ•˜๋Š” ์ž‘์—…์„ ์ „์ฒ˜๋ฆฌํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์œ ์ € ID๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

2. ๋‹จ๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„ N+1 ๋ฌธ์ œ ํ•ด๊ฒฐ

์ด์Šˆ ๋ฐœ์ƒ ํ™˜๊ฒฝ

  • ์—”ํ‹ฐํ‹ฐ๊ฐ„ ์—ฐ๊ด€ ๊ด€๊ณ„์— ์žˆ์–ด ๋งค๋ฌผ์„ ๋ฐ”๋ผ๋ณด๋Š” ์—ฌ๋Ÿฌ ์—”ํ‹ฐํ‹ฐ๋“ค์ด ์กด์žฌํ•˜์—ฌ, ์—ฌ๋Ÿฌ ์—”ํ‹ฐํ‹ฐ ๋‚ด๋ถ€์— ๋งค๋ฌผ ์ •๋ณด๊ฐ€ ์žˆ๋Š” ๋‹จ๋ฐฉํ–ฅ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ ์ ์šฉํ•œ ์ด์œ ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์—ฐ๊ด€ ๊ด€๊ณ„๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ , ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ ๊ตฌ์„ฑํ•˜์˜€๋Š”๋ฐ ์ดํ›„ ๋งค๋ฌผ ํŽ˜์ด์ง€ ์ •๋ณด๋“ค์„ ์กฐํšŒํ•˜๊ณ  ์ดํ›„ ๋งค๋ฌผ๊ณผ ์—ฐ๊ด€๋œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ์žˆ์–ด ์กฐํšŒํ•œ Page์˜ ๊ฐœ์ˆ˜ ๋งŒํผ N + 1 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ด์Šˆ ํ•ด๊ฒฐ ๊ณ ๋ฏผ ๋ฐ ํ•ด๊ฒฐ

  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋งค๋ฌผ ์—”ํ‹ฐํ‹ฐ์—์„œ ์–‘๋ฐฉํ–ฅ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  JPQL ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ API ์—์„œ ์ฟผ๋ฆฌ ํ•œ๋ฒˆ์— ์—”ํ‹ฐํ‹ฐ๋“ค์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋„ค์ดํ‹ฐ๋ธŒ ์ฟผ๋ฆฌ, IN ์ ˆ์„ ์‚ฌ์šฉํ•œ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ ๋“ฑ์ด ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์šฐ์„  Spring Data JPA ๊ณต์‹ ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด, ํŽ˜์น˜ ์กฐ์ธ + ํŽ˜์ด์ง•์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์–‘๋ฐฉํ–ฅ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ ธ๊ฐ€๋Š” ๊ฒƒ์€ ํŒ€์›๊ฐ„ ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ ์ดํ•ด ๋ฐ ์‚ฌ์šฉ์— ์žˆ์–ด ์–ด๋ ค์šธ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ๋„ค์ดํ‹ฐ๋ธŒ ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ๋Š” ๋ฐ˜ํ™˜๊ฐ’์ด ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์˜์†์„ฑ ์ปจํ…Œ์ด๋„ˆ์—์„œ ๊ด€๋ฆฌ๋ฅผ ํ•˜์ง€ ๋ชปํ•˜์—ฌ ๊ฐ์ฒด์ง€ํ–ฅ ์ฝ”๋“œ ๊ตฌํ˜„ ๋ฐ ์˜์†์„ฑ ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ์งˆ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ•˜์—ฌ, IN ์ ˆ์„ ์‚ฌ์šฉํ•œ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ๋ฅผ ์ ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ์šฐ์„  ํŽ˜์ด์ง€๋งŒํผ์˜ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ , ์กฐํšŒํ•œ ์—”ํ‹ฐํ‹ฐ๋“ค๊ณผ ์—ฐ๊ด€๋œ ์—”ํ‹ฐํ‹ฐ์˜ ID๋“ค์„ Map์œผ๋กœ ๋ณด๊ด€ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น Map์— ์กฐํšŒํ•˜๊ณ ์ž ํ•˜๋Š” ์—”ํ‹ฐํ‹ฐ์˜ ID๋“ค์„ IN์ ˆ์œผ๋กœ ํ•œ๋ฒˆ์— ์กฐํšŒํ–ˆ์Šต๋‹ˆ๋‹ค.
// SQL 3๋ฒˆ ์กฐํšŒ๋จ์„ ํ™•์ธ
Hibernate: 
    /* <criteria> */ select
        r1_0.room_id,
        r1_0.available_from,
        ...
    from
        room r1_0 
    where
        r1_0.monthly_rent<=? 
        and (
            r1_0.exclusive_area between ? and ? 
            or r1_0.exclusive_area between ? and ? 
            or r1_0.exclusive_area between ? and ?
        ) 
        and r1_0.room_id in ((select
            a1_0.room_id 
        from
            address a1_0 
        where
            a1_0.lat between ? and ? 
            and a1_0.lng between ? and ?)) 
    limit
        ?, ?
Hibernate:
         select
            l1_0.like_id,
            l1_0.member_id,
            l1_0.room_id
            ...
        from
            likes l1_0 
        where
            l1_0.room_id in (?, ?, ?) 
            and l1_0.member_id=?
Hibernate: 
        select
            i1_0.image_id,
            i1_0.image_url,
            i1_0.room_id,
            ...
        from
            image i1_0 
        where
            i1_0.room_id in (?, ?, ?) 
            and i1_0.created_at=(
                select
                    max(i2_0.created_at) 
                from
                    image i2_0 
                where
                    i2_0.room_id=i1_0.room_id
            )

๊ฐœ์„ ๋œ ์‚ฌํ•ญ

  • ์ด๋ฅผ ํ†ตํ•ด ๋ฐœ์ƒํ•˜๋Š” Hibernate ์กฐํšŒ ์ˆ˜๊ฐ€ ํ•ด๋‹น ํšŸ์ˆ˜๋งŒํผ ๊ฐ์†Œ๋œ ๊ฒƒ์„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋“ฑ๋ก๋œ ๋งค๋ฌผ ์กฐํšŒ ๋ฆฌ์ŠคํŠธ๊ฐ€ 1 + 2N ๋ฒˆ ์กฐํšŒ์—์„œ 3๋ฒˆ ์กฐํšŒ๋˜๋„๋ก ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค

3. ๊ณ„์•ฝ์„œ ์ž‘์„ฑ ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ

์ด์Šˆ ๋ฐœ์ƒ ํ™˜๊ฒฝ

  • ๊ณ„์•ฝ์„œ ์ž‘์„ฑ ์ˆœ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    1. ๊ณ„์•ฝ์„œ ์ƒ์„ฑ
    2. ์ž„๋Œ€์ธ ๊ณ„์•ฝ์„œ ์ €์žฅ
    3. ์ž„์ฐจ์ธ ๊ณ„์•ฝ์„œ ์ €์žฅ
    4. ์ž‘์„ฑ๋œ ๊ณ„์•ฝ์„œ๋ฅผ ๊ฐ์ž ์ตœ์ข… ์กฐํšŒ ํ›„ ์ˆ˜์ •
    5. ์ž„์ฐจ์ธ ์„œ๋ช…
    6. ์ž„๋Œ€์ธ ์„œ๋ช…
    7. ๊ณ„์•ฝ ์ตœ์ข… ์™„๋ฃŒ
  • ํ•ด๋‹น ๊ณผ์ •์— ์žˆ์–ด ์ž„์ฐจ์ธ ์„œ๋ช…ํ•˜๋Š” ๋™์•ˆ ์ž„๋Œ€์ธ์ด ๊ณ„์•ฝ์„œ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌํ•˜๊ณ , ์ž„์ฐจ์ธ์ด ์„œ๋ช… ์™„๋ฃŒํ•˜๋Š” ์‹œ์ ์— ๋ดค์—ˆ๋˜ ๊ณ„์•ฝ์„œ ๋‚ด์šฉ๊ณผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ด์Šˆ ํ•ด๊ฒฐ ๊ณ ๋ฏผ ๋ฐ ํ•ด๊ฒฐ

  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž„๋Œ€์ธ ๊ณ„์•ฝ์„œ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์žˆ๊ฑฐ๋‚˜, ์ž„์ฐจ์ธ์ด ์„œ๋ช…ํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋Š” ์ˆ˜๋‹จ์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฝ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ ‘๊ทผ์„ ๋ง‰๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ–ˆ๋Š”๋ฐ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” JVM ๋‚ด๋ถ€ ๋ฝ(synchronized, ReentrantLock), ์Šคํ•€๋ฝ ๊ตฌํ˜„, Redission๋ถ„์‚ฐ๋ฝ, DB ๋‚™๊ด€์ /๋น„๊ด€์  ๋ฝ ๋“ฑ์ด ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฒฐ๊ณผ์ ์œผ๋กœ Redis๋ฅผ ์‚ฌ์šฉํ•œ ๋‹จ์ˆœ ๋ฝ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ•˜์˜€๋Š”๋ฐ, ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•œ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • ์Šค๋ ˆ๋“œ์˜ ๋น„์ •์ƒ์ ์ธ ์ข…๋ฃŒ์— ๋Œ€๋น„ํ•˜์—ฌ ์ž๋™์œผ๋กœ ๋ฝ์„ ํ•ด์ œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ–ˆ๊ณ , ์ด๋Š” JVM ๋‚ด๋ถ€ ๋ฝ์€ ํ•œ๊ณ„ ์กด์žฌ
    • Heartbeat Cheking์˜ ์Šคํ•€๋ฝ์˜ ๊ฒฝ์šฐ ๋ถˆํ•„์š”ํ•œ CPU ์ ์œ  ๋ฐœ์ƒ
    • ๋ฌผ๋ฆฌ DB๋ฅผ ์ง์ ‘ ์กฐํšŒํ•˜๊ณ  ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ณ  ๋ฝ์„ ๊ฑฐ๋Š” ๊ณผ์ •์ด ๋ถˆํ•„์š”ํ•œ ๋ฌผ๋ฆฌ I/O ์—ฐ์‚ฐ์ด๋‚˜ ๋ณ‘๋ชฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค๊ณ  ํŒ๋‹จ
    • Redission ์€ TTL ์ž๋™ ์—ฐ์žฅ ๊ฐ™์€ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์ด ์กด์žฌํ•˜์ง€๋งŒ ํ˜„์žฌ ๋ฝ ์š”๊ตฌ ์ˆ˜์ค€์—์„œ๋Š” ๊ณ„์•ฝ ๊ด€๋ จ 2๋ช…๋งŒ์ด ํ•˜๋‚˜์˜ ๊ณ„์•ฝ์„œ์— ์ ‘๊ทผํ•˜๊ณ  ์žˆ์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋„์ž…์ด ๊ณผ๋„ํ•˜๋‹ค๊ณ  ํŒ๋‹จ
    • ํ˜„์žฌ ํ”„๋กœ์ ํŠธ๋Š” ๋ชจ๋†€๋ฆฌ์‹ ๊ตฌ์กฐ๋กœ ๋ถ„์‚ฐ ํ™˜๊ฒฝ์„ ๊ณ ๋ คํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ, ์ดํ›„ MSA๊ตฌ์กฐ๋กœ ํ™•์žฅ์ด ์šฉ์ด
    • ํ•ด๋‹น ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•œ ์‹œ์ ์—์„œ ์ด๋ฏธ ์ฑ„ํŒ… ๊ด€๋ จ์œผ๋กœ Redis๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ
    • ์ด๋ฅผ ํ†ตํ•ด ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜์ธ Redis์˜ TTL์„ ํ†ตํ•ด ๋ฝ ์ž๋™ ํ•ด์ œ๋ฅผ ๋ชฉํ‘œ
  • ์ด๋ฅผ ํ†ตํ•ด ๊ธฐ์กด ์„œ๋น„์Šค์—์„œ ํ˜ธ์ถœํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์šฉ์ดํ•˜๋„๋ก ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ํผ์‚ฌ๋“œ ํŒจํ„ด์„ ์ ์šฉํ•˜์—ฌ Redis Lock์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
    • @RedisLock(key = "'contract:' + #requestDto.contractId", errorCode = RedisLockErrorCode.*LANDLORD_IN_PROGRESS*) ์™€ ๊ฐ™์ด ์ปค์Šคํ…€ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์„œ๋น„์Šค ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ์„œ๋น„์Šค๋Š” ๋ฝ์„ ์†Œ์œ ์ž๋งŒ ํ•ด์ œํ•  ์ˆ˜ ์žˆ๋„๋ก Lua ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  setIfAbsent() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด Redis ๋‚ด๋ถ€์ ์œผ๋กœ SENTX๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฝ์„ ์†Œ์œ ํ•œ ๋‹จ์ผ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ์ถ”๊ฐ€์ ์œผ๋กœ CountDownLatch๋ฅผ ์‚ฌ์šฉํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ ์ด๋ฏธ์ง€

๊ฐœ์„ ๋œ ์‚ฌํ•ญ

  • ๊ธฐ์กด ๋กœ์ง์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ , ์ปค์Šคํ…€ ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์›ํ•˜๋Š” ๋„๋ฉ”์ธ, ํŠน์ • ์„œ๋น„์Šค์— Redis Lock์„ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๋กœ์ง์ด ๋‹ค๋ฅธ ํŒ€์›์—๊ฒŒ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€์Œ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ™”๋ฉด ๊ตฌ์„ฑ

1. ์นด์นด์˜ค ๋กœ๊ทธ์ธ

์นด์นด์˜ค ๋กœ๊ทธ์ธ


2. ๋งค๋ฌผ ๋“ฑ๋ก

์ž„๋Œ€์ธ ๋งค๋ฌผ ์ •๋ณด ๋“ฑ๋ก

๋“ฑ๋ก ๋งค๋ฌผ ๊ฒ€์ฆ


3. ๋งค๋ฌผ ์กฐํšŒ ๋ฐ ๋“ฑ๊ธฐ๋ถ€๋“ฑ๋ณธ ์œ„ํ—˜๋„ ๋ถ„์„

๋งค๋ฌผ ์กฐํšŒ


4. ๋ฌธ์˜ ์ฑ„ํŒ…

๊ณ„์•ฝ ๋ฌธ์˜ ์ฑ„ํŒ…


5. ๊ณ„์•ฝ์„œ ์ž‘์„ฑ

์ž„๋Œ€์ธ ๊ณ„์•ฝ์„œ ์ž‘์„ฑ


6. ๊ณ„์•ฝ์„œ ์ฑ—๋ด‡

๊ณ„์•ฝ์„œ ์ฑ—๋ด‡


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

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

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages