/khumu-community

๐ŸŒŸ ๊ฒฝํฌ๋Œ€ํ•™๊ต ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ฟ ๋ฎค์˜ ์ค‘์‹ฌ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” Spring Boot ์„œ๋ฒ„

Primary LanguageJava

khumu-community ์„ค๊ณ„

์ปค๋ฎค๋‹ˆํ‹ฐ๋ผ๋Š” ์ฟ ๋ฎค์˜ ์ค‘์‹ฌ์ด ๋˜๋Š” ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๊ณ ์žํ•œ๋‹ค.

๊ธฐ์กด์—๋Š” Django๋ฅผ ์ด์šฉํ•ด์„œ khumu-command-center ๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฐ ๊ฒฝํฌ๋Œ€ ๊ด€๋ จ ํ˜น์€ ๊ณ„์ • ๊ด€๋ จ ๊ธฐ๋Šฅ๋“ค์„ ์ˆ˜ํ–‰ํ–ˆ์ง€๋งŒ ์ด์ œ๋Š” Java Spring Boot๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ด์šฉํ•˜๋ คํ•œ๋‹ค.

khumu-community์˜ ์ฃผ์š” ๊ธฐ๋Šฅ

  • ์œ ์ €์— ๋Œ€ํ•œ CRUD
  • โœ… 1๏ธโƒฃ ์œ ์ €์— ๋Œ€ํ•œ ์ฐจ๋‹จ ๊ธฐ๋Šฅ (๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ์ž ์ฐจ๋‹จํ•˜๊ธฐ)
  • ๊ฒŒ์‹œํŒ์— ๋Œ€ํ•œ CRUD
  • ๊ฒŒ์‹œํŒ์— ๋Œ€ํ•œ Follow / Unfollow
  • โœ… 1๏ธโƒฃ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ CRUD
    • โœ… 1๏ธโƒฃ ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ, ๋Œ“๊ธ€ ๋‹จ, ์ข‹์•„์š”ํ•œ ๋“ฑ ๊ฐ๊ฐ์˜ ๋‹ค์–‘ํ•œ ๊ธฐ์ค€์œผ๋กœ ๊ฒŒ์‹œ๊ธ€์„ ์กฐํšŒํ•˜๊ธฐ
    • โœ… 1๏ธโƒฃ comment ์„œ๋ฒ„์—์„œ comment ๊ฐœ์ˆ˜ ๊ฐ€์ ธ์˜ค๊ธฐ
    • โœ… 1๏ธโƒฃ alimi ์„œ๋ฒ„์—์„œ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ ์•Œ๋ฆผ ๊ตฌ๋… ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
  • 1๏ธโƒฃ ๊ฒŒ์‹œ๊ธ€/๊ฒŒ์‹œํŒ์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ
  • 1๏ธโƒฃ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ์‹œ๊ฐ ํ‘œํ˜„
  • โœ… 1๏ธโƒฃ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ Like / Unlike
  • โœ… 1๏ธโƒฃ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ Bookmark / Unbookomark
  • 1๏ธโƒฃ ๋‹ค์–‘ํ•œ ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•œ ์‹ ๊ณ  ๊ธฐ๋Šฅ
  • ํ•™์‚ฌ ์ผ์ •์— ๋Œ€ํ•œ Read - ํŒŒ์ด์ฌ์œผ๋กœ ํ•  ์ง€ ๊ณ ๋ฏผ
    • ๊ทผ๋ฐ ํŒŒ์ด์ฌ์œผ๋กœ ํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋ถˆํ•„์š”ํ•œ microserviceํ™”๊ฐ€ ๋  ๊ฒƒ ๊ฐ™๋‹ค.
  • ์•ฑ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ Create
  • ํ•™๊ต ๊ฐ•์˜, ํ•™๊ณผ ์ •๋ณด ํฌ๋กค๋ง, Read

์ผ๋‹จ์€ 1๏ธโƒฃ๋กœ ํ‘œ์‹œํ•œ ์œ ์ €, ๊ฒŒ์‹œ๊ธ€ ๊ด€๋ จ ๊ธฐ๋Šฅ๋“ค์„ ๊ฐœ๋ฐœํ•˜๊ณ 

๊ฒŒ์‹œํŒ์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ๋„ ๊ฐœ๋ฐœํ•˜๊ณ 

๋‚˜๋จธ์ง€ ํ•™์‚ฌ์ผ์ •์ด๋‚˜ ํ•™๊ต ๊ด€๋ จ ๊ธฐ๋Šฅ๋“ค์€ khumu-command-center์— ์žˆ๋˜ ์ฝ”๋“œ๋กœ ๋ฒ„ํ…จ๋ณด๋Š” ๊ฒŒ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

์ €์žฅ์†Œ ์„ค๊ณ„

  • ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” RDB + JPA์˜ ์กฐํ•ฉ
  • Redis cache๋ฅผ ์“ฐ๊ธฐ ์ข‹์€ ๋ถ€๋ถ„์ด ์žˆ๋Š”๊ฐ€?
    • ๋‚ด๊ฐ€ ํŒ”๋กœ์šฐ ์ค‘์ธ ๊ฒŒ์‹œํŒ ๋ชฉ๋ก

      • ๊ฐ„๋‹จํ•˜๊ฒŒ ํŒ”๋กœ์šฐ ์ž‘์—…๊ณผ Synchronousํ•˜๊ฒŒ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋‚ด ํ”ผ๋“œ์— ๋ณด์—ฌ์งˆ ์ตœ๊ทผ ๊ฒŒ์‹œ๊ธ€๋“ค

      • ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๊ธ€์„ ์ผ๋‹ค๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋… ํ›„ ์ฒ˜๋ฆฌ
        • ํ•ด๋‹น ๊ธ€์˜ ๊ฒŒ์‹œํŒ์„ ๊ตฌ๋…ํ•˜๋Š” ์œ ์ €๋“ค์— ๋Œ€ํ•œ ํ”ผ๋“œ ๊ฒŒ์‹œ๊ธ€ ID ์บ์‹œ์— ํ•ด๋‹น ๊ธ€์˜ ID๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
      • ๋‚ด๊ฐ€ ๊ฒŒ์‹œํŒ์„ ํŒ”๋กœ์šฐ ํ–ˆ์„ ๋•Œ
        • ํ•ด๋‹น ๊ฒŒ์‹œํŒ์˜ ์ตœ๊ทผ ๊ธ€๋“ค ์ค‘ N๊ฐœ ์ •๋„์˜ ID๋ฅผ ์ž์‹ ์˜ ํ”ผ๋“œ ๊ฒŒ์‹œ๊ธ€ ID ์บ์‹œ์— ์ถ”๊ฐ€ํ•œ๋‹ค.

      ๋‚ด ํ”ผ๋“œ์— ๋ณด์—ฌ์งˆ ์ตœ๊ทผ ๊ฒŒ์‹œ๊ธ€ ID๋“ค์„ Redis์— ์บ์‹œํ•˜๋ฉด ์ข‹์€ ์ ์€? (๋ญ๊ฐ€ ์žˆ์„๊นŒ..?)

      • ๋ณด๊ณ ์žํ•˜๋Š” ID๋ฅผ ๋ฏธ๋ฆฌ ์บ์‹œํ•ด๋†“์œผ๋ฉด JOIN์ด๋‚˜ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ” ์กฐํšŒ ์—†์ด PK์— ๋Œ€ํ•œ in-query๋งŒ์œผ๋กœ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
      • โ“ ๊ทผ๋ฐ ์‹ค์ œ๋กœ ์ฒด๊ฐ๋ ๋งŒํ•œ ํšจ๊ณผ๊ฐ€ ์žˆ์„ ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์Œ.
    • Generalํ•œ ๋‚ด์šฉ๋“ค

      • ํ•ซ ๊ฒŒ์‹œ๊ธ€ N๊ฐœ โ† is_hot์— ๋Œ€ํ•œ index๋Š” ๋งŒ๋“ค๊ธฐ ์‹ซ๊ธฐ ๋•Œ๋ฌธ์— ํ•ซ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ ์กฐํšŒ๋Š” Redis์— ์ €์žฅํ•˜๋ฉด ํŽธํ•˜๊ณ  ๋น ๋ฅด๊ธด ํ•  ๋“ฏ. ๊ทผ๋ฐ ์ฒด๊ฐ๋  ์ •๋„์ผ ์ง€๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ์Œ.
  • DynamoDB๋ฅผ ์“ฐ๊ธฐ ์ข‹์€ ๋ถ€๋ถ„์ด ์žˆ๋Š”๊ฐ€?
    • ํˆฌ ๋จธ์น˜์ธ ๋“ฏ.

์ด๋ฒคํŠธ ์„ค๊ณ„

  • ์œ ์ € ์ƒ์„ฑ
    • slack ์•Œ๋ฆผ
    • alimi๊ฐ€ ์•Œ๋ฆผ ์„ค์ •์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•จ
  • ์œ ์ € ์‚ญ์ œ
    • slack ์•Œ๋ฆผ
  • ์œ ์ € ์ฐจ๋‹จ
  • ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ฑ
    • slack ์•Œ๋ฆผ
    • ๋Œ“๊ธ€ ์„œ๋ฒ„๊ฐ€ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ์ž ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•˜๊ธฐ ์œ„ํ•จ.
    • ๊ฒŒ์‹œ๊ธ€์˜ ๊ฒŒ์‹œํŒ์„ Follow ์ค‘์ธ user๋“ค์˜ Feed Article ID list๋ฅผ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•จ.
  • ๊ฒŒ์‹œ๊ธ€ ์ข‹์•„์š”
    • ์ผ์ • ๊ฐœ์ˆ˜๊ฐ€ ๋„˜์œผ๋ฉด Hot ๊ฒŒ์‹œ๊ธ€๋กœ ์„ ์ •ํ•˜๊ธฐ ์œ„ํ•จ.
    • ์ผ์ • ๊ฐœ์ˆ˜๊ฐ€ ๋„˜์œผ๋ฉด ์ž‘์„ฑ์ž์—๊ฒŒ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•จ. โ† ๋ณ„๋กœ ํ•„์š” ์—†์„ ๋“ฏ
  • ๊ฒŒ์‹œ๊ธ€ ์‹ ๊ณ 
  • ํ•ซ ๊ฒŒ์‹œ๊ธ€ ์„ ์ •
    • ์ž‘์„ฑ์ž์—๊ฒŒ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•จ.
    • ์ƒˆ๋กœ์šด ํ•ซ ๊ฒŒ์‹œ๊ธ€ ์„ ์ • ๊ด€๋ จ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•จ. โ† ์ด๊ฒƒ๋„ ๋ณ„๋กœ ํ•„์š” ์—†์„ ๊ฒƒ ๊ฐ™๊ธด ํ•จ.
  • ๋Œ“๊ธ€, ๋Œ€๋Œ“๊ธ€ ์ƒ์„ฑ โ†’ ์ด๊ฑด ๋Œ“๊ธ€ ์„œ๋ฒ„๊ฐ€ ์•Œ์•„์„œ ํ•˜๊ฒ ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ŠคํŠธ๋Ÿญ์ณ

  • ๋จผ์ € Context๋ฅผ ๋‚˜๋ˆ„๋Š” ๊ฑด ํˆฌ๋จธ์น˜๊ฐ™๋‹ค. ๋ช‡ ๊ฐ€์ง€ ์‚ฌ์ด๋“œ ํ”„๋กœ์ ํŠธ๋“ค์˜ ๊ตฌ์กฐ๋ฅผ ์ฐธ๊ณ ํ–ˆ์ง€๋งŒ Context๋ฅผ ๋‚˜๋ˆ ์„œ ์žฅ์ ์„ ์ž˜ ์ด๋Œ์–ด๋‚ด๋Š” ์ผ€์ด์Šค๋Š” ๋“œ๋ฌผ์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.
  • ํ—ฅ์‚ฌ๊ฑฐ๋„์€ Application(๋‚ด๋ถ€)์™€ Infrastructure(์™ธ๋ถ€)๋กœ ๋‚˜๋‰œ๋‹ค.
    • Inbound Adapter๋Š” Inbound Port๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ Inbound port๊ฐ€ ์‹ค์ œ ์™ธ๋ถ€์—์„œ ๋“ค์–ด์˜ค๋Š” input์„ ์ž˜ ๋ฐ›์•„๋“ค์ด๊ณ  ๋™์ž‘ํ•œ ๋’ค Inbound port๊ฐ€ ์‘๋‹ตํ•˜๋Š” output์„ ์‹ค์ œ ์™ธ๋ถ€๊ฐ€ ์ž˜ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•ด์ค€๋‹ค.
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(๋‚ด๋ถ€)๋Š” ์ž์‹ ์ด ํ˜ธ์ถœํ•  Outbound port๋ฅผ ์ •์˜ํ•˜๊ณ  Outbound port๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. Outbound Adapter๋Š” ๋‚ด๋ถ€๊ฐ€ ์ •์˜ํ•œ Outbound port๋ฅผ ๊ตฌํ˜„ํ•จ์œผ๋กœ์จ ๋‚ด๋ถ€๊ฐ€ ์ •์˜ํ•œ ๋ฐฉ์‹์œผ๋กœ ์‹ค์ œ ์™ธ๋ถ€์— ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.
โ”œโ”€โ”€ config   // config ๊ด€๋ จ Class๋“ค ์ •์˜
โ”‚
โ”œโ”€โ”€ infra   // ์™ธ๋ถ€ ์˜์—ญ
โ”‚   โ”œโ”€โ”€ controller   // ๊ฒŒ์‹œ๊ธ€, ๊ฒŒ์‹œํŒ, ์œ ์ €์— ๋Œ€ํ•œ Controller
โ”‚   โ”‚   db    // JPA๋ฅผ ์ด์šฉํ•ด application.port.repository ๊ตฌํ˜„
โ”‚   โ””โ”€โ”€ cache   // cache ๊ด€๋ จ ๋‚ด์šฉ
โ”‚
โ”œโ”€โ”€ application   // ๋‚ด๋ถ€ ์˜์—ญ
โ”‚   โ”œโ”€โ”€ execption   // ๋‚ด๋ถ€๊ฐ€ catchํ•˜๊ฑฐ๋‚˜ throwํ•ด์ค„ Exception
โ”‚   โ”‚   domain   // ๋„๋ฉ”์ธ ๊ฐ์ฒด
โ”‚   โ”‚   vo    // VO๋กœ ์“ธ๋งŒํ•œ ๊ฑฐ ์žˆ์œผ๋ฉด ์ •์˜
โ”‚   โ”‚   dto   // ๋‚ด๋ถ€๊ฐ€ ์ธํ’‹์œผ๋กœ ๋ฐ›๊ฑฐ๋‚˜ ์•„์›ƒํ’‹์œผ๋กœ ๋–จ๊ถˆ์ค„ DTO
โ”‚   โ”‚   port
โ”‚   โ”‚   โ”œโ”€โ”€ in
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ service // inbound port๋กœ์„œ service๋ฅผ ์ •์˜
โ”‚   โ”‚   โ””โ”€โ”€ out
โ”‚   โ”‚       โ”œโ”€โ”€ repository
โ”‚   โ”‚       โ”‚   cache
โ”‚   โ”‚       โ””โ”€โ”€ messaging`
โ”‚   โ””โ”€โ”€ mapper
โ”‚
โ””โ”€โ”€ common
    โ””โ”€โ”€ util