codestates-seb / seb45_main_026

๐Ÿง‘โ€๐Ÿ’ป ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๊ธฐ ์œ„ํ•œ ์„ ํƒ, Prometheus

Home Page:https://www.itprometheus.net/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Team. OppenHeimer

๋Œ€ํ‘œ ์ด๋ฏธ์ง€
IT ๊ต์œก ์˜คํ”ˆ ํ”Œ๋žซํผ

๐Ÿง‘โ€๐Ÿ’ป ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๊ธฐ ์œ„ํ•œ ์„ ํƒ, Prometheus

ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„: 2023.08.24 ~ 2023.09.22

๐Ÿ”— ๋ฐฐํฌ์ฃผ์†Œ : PROMETHEUS

  • ๊ฒŒ์ŠคํŠธ์šฉ ID/PW : guest@gmail.com / 1q2w3e4r!
  • ๋งˆ์Œ์— ๋“œ์‹ ๋‹ค๋ฉด โญ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ใ…Žใ…Ž

๐Ÿ›ซ ์†Œ๊ฐœ

๐Ÿง ๋ถ€๋‹ด์—†์ด IT ๊ต์œก ๋™์˜์ƒ์„ ๋ณด๊ณ  ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„์ด ์—†์„๊นŒ? ๊ฐ€๋ฒผ์šด ๋งˆ์Œ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋Š” IT ์˜์ƒ์ด ์žˆ์—ˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค..

  • ์–ด๋–ค ์ž๊ฒฉ ์กฐ๊ฑด์ด๋‚˜ ์‹ฌ์‚ฌ ์—†์ด ์ž์‹ ๋งŒ์˜ IT ๋…ธํ•˜์šฐ๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ฐ๊ณ  ์˜ฌ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๐Ÿ’ธ ๋ฌด๋ฃŒ ์˜์ƒ, ๋ฆฌ์›Œ๋“œ ์ ๋ฆฝ๊นŒ์ง€ ๋‹ค์–‘ํ•œ ํ˜œํƒ์ด ์žˆ์–ด์š”.
  • ๊ตฌ๋…, ์นดํ…Œ๊ณ ๋ฆฌ ๋“ฑ์œผ๋กœ ์ž์‹ ์—๊ฒŒ ์•Œ๋งž์€ ์˜์ƒ์„ ์ฐพ์œผ์„ธ์š”!

๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง ํŒ€์› ์†Œ๊ฐœ

๊น€ํ˜œ๋ฆผ ๋ฐฉ์Šนํ™˜ ์ด์ข…๋ฒ” ๊น€ํ˜ธ๋นˆ ๊น€์ง„์•„ ํ•จ์˜ˆ์ค€
๊น€ํ˜œ๋ฆผ ๋ฐฉ์Šนํ™˜ ์ด์ข…๋ฒ” ๊น€ํ˜ธ๋นˆ ๊น€์ง„์•„ ํ•จ์˜ˆ์ค€
FE ๋ถ€ํŒ€์žฅ FE FE BE ํŒ€์žฅ BE BE
FE ๋‹ด๋‹น ํŒŒํŠธ (๐Ÿ‘ˆ Click)
  • ๊น€ํ˜œ๋ฆผ(๋ถ€ํŒ€์žฅ)
    • ์‚ฌ์šฉ์ž ์ธ์ฆ, OAuth, ํšŒ์›์ •๋ณด ๊ด€๋ฆฌ ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ๊ฒฐ์ œ ๋ชฉ๋ก, ๋ฆฌ์›Œ๋“œ ๋ชฉ๋ก ๋ฌดํ•œ์Šคํฌ๋กค ์ ์šฉ
    • React hook form ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ ์šฉ
    • ์‹œ์ž‘ ํŽ˜์ด์ง€ ๊ตฌํ˜„
    • ํด๋ฆฐ ์ฝ”๋“œ๋ฅผ ๊ณ ๋ คํ•œ Custom hook, ์žฌํ™œ์šฉ ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„, API ๋กœ์ง ๋ถ„๋ฆฌ
    • ๋””์ž์ธ ์‹œ์Šคํ…œ, storybook ์ ์šฉ
    • ํด๋ผ์ด์–ธํŠธ ๋ฐฐํฌ ๊ด€๋ฆฌ

  • ๋ฐฉ์Šนํ™˜
    • ์˜์ƒ ํ•„ํ„ฐ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ๊ฒ€์ƒ‰๊ธฐ๋Šฅ ๋ฐ ์ž๋™์™„์„ฑ ๊ตฌํ˜„
    • ๊ฐ•์˜ ๋ฐ ์ฑ„๋„ ๋ชฉ๋ก ์ „๋ฐ˜ ๊ตฌํ˜„ ๋ฐ ๋ฌดํ•œ์Šคํฌ๋กค ์ ์šฉ
    • ์ฑ„๋„ํŽ˜์ด์ง€ ๊ตฌํ˜„

  • ์ด์ข…๋ฒ”
    • S3 Presign-url๋ฅผ ํ†ตํ•œ ์ด๋ฏธ์ง€ ๋ฐ ๋™์˜์ƒ ์—…๋กœ๋“œ
    • ๊ฐ•์˜ ๋ฌธ์ œ CRD
    • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฆฌ์ŠคํŠธ CRUD
    • TossPayment ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ ์šฉ
    • React-Player ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ ์šฉ, ์ปค์Šคํ…€ ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„, 1๋ถ„ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
    • ๋ฆฌ๋ทฐ CRUD, ํ•„ํ„ฐ ๊ธฐ๋Šฅ, Pagination
    • ๋‚ด ๊ฐ•์˜ ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™” ๊ธฐ๋Šฅ

BE ๋‹ด๋‹น ํŒŒํŠธ (๐Ÿ‘ˆ Click)
  • ๊น€ํ˜ธ๋นˆ(ํŒ€์žฅ)
    • AWS ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„ ๋ฐ ํ™˜๊ฒฝ ๊ตฌ์ถ•
    • Git Actions CI/CD ๊ตฌ์ถ•
    • Logging ๋ฐ Cloudwatch ๋ชจ๋‹ˆํ„ฐ๋ง
    • API Rest docs ๋ฌธ์„œํ™”
    • ๋น„๋””์˜ค ๊ด€๋ จ ๊ธฐ๋Šฅ, ์ฃผ๋ฌธ/๊ฒฐ์ œ ๊ธฐ๋Šฅ, ์ฑ„๋„ ๊ณต์ง€์‚ฌํ•ญ ๊ธฐ๋Šฅ

  • ๊น€์ง„์•„
    • ์ฑ„๋„ ๊ธฐ๋Šฅ
    • T๋น„๋””์˜ค ๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ
    • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ(์ฑ„๋„, ๋ฆฌ๋ทฐ, ๊ณต์ง€์‚ฌํ•ญ)

  • ํ•จ์˜ˆ์ค€
    • ๋กœ๊ทธ์ธ ๋ฐ ํšŒ์›๊ฐ€์ž…, OAuth (์ธ์ฆ ๋ฐ ์ธ๊ฐ€ ๊ธฐ๋Šฅ) ๊ธฐ๋Šฅ
    • ํšŒ์› ์ •๋ณด ๊ด€๋ จ CRUD ๊ธฐ๋Šฅ
    • API Rest docs ๋ฌธ์„œํ™”
    • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ(ํšŒ์›, ๋น„๋””์˜ค, ์ธ์ฆ, ์ฃผ๋ฌธ)


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

Front-end

HTML5 CSS3 JavaScript React Redux Toolkit Axios styled components React Hook Form React Router Storybook


Back-end

Java

Spring Boot jwt jwt JPA queryDsl Spring Boot Spring Boot

mysql Redis


Dev-Ops & Tool

Git AWS Docker


๐Ÿ’ก ์•„์ด๋””์–ด

์•„์ด๋””์–ด ํ™•์ธ (๐Ÿ‘ˆ Click)

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

๋”ฐ๋ผ์„œ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋ˆ„๊ตฌ๋‚˜ ์ƒ์‚ฐ์ž์ด์ž ์†Œ๋น„์ž๊ฐ€ ๋  ์ˆ˜ ์žˆ๋„๋ก IT ๊ต์œก ์˜คํ”ˆ ํ”Œ๋žซํผ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋น„์Šค๋ฅผ ๊ธฐํšํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฌด๋ฃŒ ๋™์˜์ƒ ์—…๋กœ๋“œ, ๋ฆฌ๋ทฐ ์ž‘์„ฑ, ๋ฌธ์ œ ํ’€๊ธฐ ๋“ฑ์˜ ํ™œ๋™์œผ๋กœ ์‰ฝ๊ฒŒ ๋ฆฌ์›Œ๋“œ๋ฅผ ์ ๋ฆฝํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ๋„ํ•˜์—ฌ ํ”Œ๋žซํผ์˜ ์ด์šฉ์ด ์„ ์ˆœํ™˜๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


๐Ÿ“„ ๊ฐœ๋ฐœ ๋ฌธ์„œ

๐Ÿ“ˆ ERD

ERD ๋ณด๊ธฐ (๐Ÿ‘ˆ Click)
ERD

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

์•„ํ‚คํ…์ฒ˜ ์ƒ์„ธ ํ™•์ธ (๐Ÿ‘ˆ Click)
architecture

์›น ํด๋ผ์ด์–ธํŠธ

  • S3 ๋ฒ„ํ‚ท์— ์›น ์„œ๋ฒ„ ๋ฐฐํฌ
  • CloudFront ์™€ Route53 ์„ ํ†ตํ•ด ๋ผ์šฐํŒ…, HTTPS ์„œ๋ฒ„ ๊ตฌ์ถ•, ์ •์  ํŒŒ์ผ ์บ์‹ฑ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„

  • private subnet ์— ์™ธ๋ถ€์™€ ๊ฒฉ๋ฆฌํ•˜์—ฌ ๋ฐฐํฌ, NAT instance ๋กœ ์•„์›ƒ๋ฐ”์šด๋“œ ํ†ต์‹ 
  • Load Balancer ์™€ Auto Scaling Group ์œผ๋กœ ํŠธ๋ž˜ํ”ฝ ๋ถ„์‚ฐ, ๊ฐ€์šฉ์„ฑ ํ™•๋ณด

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค

  • RDS(MySQL) ์ด์ค‘ํ™” ๊ตฌ์„ฑ, Redis Cluster ๊ตฌ์ถ•

CloudWatch

์ •์  ๋ฆฌ์†Œ์Šค ํŒŒ์ผ

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ง์ ‘ s3 ๋ฒ„ํ‚ท์— ์—…๋กœ๋“œ (presignedUrl ํ™œ์šฉ)
  • CloudFront ๋กœ ํŒŒ์ผ ์บ์‹ฑ

๐Ÿ“ธ ์„œ๋น„์Šค ํŽ˜์ด์ง€

์„œ๋น„์Šค ํŽ˜์ด์ง€ ํ™•์ธ (๐Ÿ‘ˆ Click)
์‹œ์ž‘ ํŽ˜์ด์ง€ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-18 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1 39 50 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-14 แ„‹แ…ฉแ„’แ…ฎ 2 49 40
ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ ํŽ˜์ด์ง€
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-14 แ„‹แ…ฉแ„’แ…ฎ 2 50 35 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-14 แ„‹แ…ฉแ„’แ…ฎ 2 59 44
๊ฐ•์˜ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๊ฐ•์˜ ์ƒ์„ธ ํŽ˜์ด์ง€
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-18 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1 40 25 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-14 แ„‹แ…ฉแ„’แ…ฎ 2 53 21
๋ฌธ์ œํ’€๊ธฐ ํŽ˜์ด์ง€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-14 แ„‹แ…ฉแ„’แ…ฎ 2 56 37 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-14 แ„‹แ…ฉแ„’แ…ฎ 2 56 52
๊ฐ•์˜ ์—…๋กœ๋“œ ํŽ˜์ด์ง€ ๋ฌธ์ œ ์—…๋กœ๋“œ ํŽ˜์ด์ง€
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-15 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 10 50 06 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-14 แ„‹แ…ฉแ„’แ…ฎ 2 58 13
์ฑ„๋„ ์ •๋ณด ํŽ˜์ด์ง€ ๊ตฌ๋… ๋ชฉ๋ก ํŽ˜์ด์ง€
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-18 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1 41 22 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-15 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 10 54 46
๋ฆฌ์›Œ๋“œ ์กฐํšŒ ํŽ˜์ด์ง€ ๊ฒฐ์ œ ๋‚ด์—ญ ํŽ˜์ด์ง€
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-15 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 11 00 53 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-18 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1 53 10
์ •์‚ฐ๋‚ด์—ญ ํŽ˜์ด์ง€ ์‹œ์ฒญ๊ธฐ๋ก ํŽ˜์ด์ง€
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-15 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 11 00 53 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-18 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1 46 48
๊ด€๋ฆฌ์ž์šฉ - ์‹ ๊ณ ๋œ ๋น„๋””์˜ค ๋ชฉ๋ก ๊ด€๋ฆฌ์ž์šฉ - ์‹ ๊ณ  ๋น„๋””์˜ค ์ƒ์„ธ
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-15 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 11 00 53 แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-18 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1 46 48

โœจ [FE] ์™œ/์–ด๋–ป๊ฒŒ ์ด ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ–ˆ๋‚˜์š”?

FE ๊ธฐ์ˆ  ์ƒ์„ธ ์„ค๋ช… ํ™•์ธ (๐Ÿ‘ˆ Click)

React Hook Form

๋„ˆ๋ฌด ๋งŽ์€ input state๊ด€๋ฆฌ๋กœ ์ธํ•œ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ ์ €ํ•˜์™€ ์žฆ์€ ํ™”๋ฉด ์žฌ๋žœ๋”๋ง์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. React Hook Form ์€ input ์ž…๋ ฅ๊ฐ’์„ ref ํ˜•์‹์œผ๋กœ ์ œ์–ดํ•˜์—ฌ ํ™”๋ฉด์˜ ์žฌ๋žœ๋”๋ง์„ ์ตœ์†Œํ™”ํ•˜๊ณ , register, handleSubmit, formState, useWatch ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋ณต์žกํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

Custom Hook

๋ฐ˜๋ณต ์‚ฌ์šฉ๋˜๋Š” ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Custom Hook์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. Refresh Token์„ ์ด์šฉํ•œ Authorization ํ† ํฐ ์žฌ๋ฐœ๊ธ‰ ๋กœ์ง ์žฌํ™œ์šฉ useLogout, useLongPress useConfirm ๋“ฑ์˜ ๋กœ์ง์„ ์žฌํ™œ์šฉ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

react-intersection-observer

๋ฌดํ•œ ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. styled-component๋ฅผ ์‚ฌ์šฉํ•œ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ useRef๋‚˜ addEventListener๋“ฑ์„ ๋”ฐ๋กœ ์„ค์ •ํ•  ํ•„์š” ์—†์ด useInView๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ ์Šคํฌ๋กค ๋ฐ”๋‹ฅ ๊ฐ์ง€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Redux Toolkit with Persistent

๋กœ๊ทธ์ธ ์ •๋ณด, ์œ ์ € ์ •๋ณด, ๋‹คํฌ๋ชจ๋“œ ๋“ฑ UI ์„ค์ • ์ •๋ณด, ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ •๋ณด, ์žฌ์ƒ ๋น„๋””์˜ค ์ •๋ณด ๋“ฑ์„ ์ „์—ญ ์ƒํƒœ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ Redux Toolkit์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. Redux Toolkit์„ ์‚ฌ์šฉํ•˜๋ฉด Redux์—์„œ action ์ƒ์„ฑ์„ ๋”ฐ๋กœ ์ž‘์„ฑํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์œผ๋ฉฐ, redux-persist์˜ ์ถ”๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ฉํ•˜์—ฌ ์›ํ•˜๋Š” ์ƒํƒœ ์ •๋ณด๋งŒ ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์— ์ž๋™์œผ๋กœ ์ €์žฅ๋˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

react-player

react-player ์‚ฌ์šฉ์˜ˆ์‹œ

๊ธฐ์กด์˜ video ํƒœ๊ทธ์—์„œ์˜ ๊ธฐ๋Šฅ๋“ค์„ ์ข€ ๋” ์‰ฝ๊ฒŒ ์†์„ฑ๋“ค์„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์„œ, ์ปค์Šคํ…€ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค ๋•Œ react-player์— ๋‚ด์žฅ๋œ ๋ฉ”์„œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•ด ๊ธฐ์กด๋ณด๋‹ค ๊ฐ„ํŽธํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Storybook & Figma Token

๋‹คํฌ๋ชจ๋“œ/๋ผ์ดํŠธ๋ชจ๋“œ switch storybook
๋‹คํฌ๋ชจ๋“œ ์˜ˆ์‹œ

๐Ÿ‘‰๐Ÿป storybook chromatic ๋ฐฐํฌ ๋งํฌ ๋ฐ”๋กœ๊ฐ€๊ธฐ

์ „์ฒด ํ™”๋ฉด ๋””์ž์ธ์˜ ํ†ต์ผ์„ฑ์„ ์ง€ํ‚ค๊ณ  ๋‹คํฌ๋ชจ๋“œ ๋“ฑ ์ „์ฒด UI ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด์„œ Figma Token์„ ์ ์šฉํ•˜์˜€์œผ๋ฉฐ, ์žฌ์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ์˜ ๋””์ž์ธ์„ ํ™•์ธํ•˜๋ฉฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Storybook์„ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

CSS keyframes

๋ฉ”์ธํŽ˜์ด์ง€์˜ Viewport ์• ๋‹ˆ๋ฉ”์ด์…˜๊ณผ ๋กค๋ง ๋ฐฐ๋„ˆ, ์‚ฌ์ด๋“œ๋ฐ” ๋””์ž์ธ์„ ์œ„ํ•ด์„œ styled-component์— keyframes๋ฅผ ์ ์šฉํ•˜์—ฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

react-flicking

๋ฉ”์ธํŽ˜์ด์ง€ ๋‘ ๋ฒˆ์งธ ํŽ˜์ด์ง€์— ์Šฌ๋ผ์ด๋“œ ๋ฐฐ๋„ˆ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ react-flicking UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.


โœจ [BE] ์™œ/์–ด๋–ป๊ฒŒ ์ด ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ–ˆ๋‚˜์š”?

BE ๊ธฐ์ˆ  ์ƒ์„ธ ์„ค๋ช… ํ™•์ธ (๐Ÿ‘ˆ Click)

API ๋ฌธ์„œํ™”

๋ฌธ์„œ ๋ฉ”์ธ ํŽ˜์ด์ง€ API์— ๋”ฐ๋ฅธ ์ƒ์„ธ ํŽ˜์ด์ง€

Swagger ๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ API ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌธ์„œ๊ฐ€ ์‹ค์ œ API์™€ ๋‹ค๋ฅด๊ฑฐ๋‚˜ ์„ฑ๋Šฅ์„ ๋ณด์žฅ ๋ฐ›์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๊ฒ€์ฆ๋œ API ์˜ ์ œ๊ณต๊ณผ ๊น”๋”ํ•œ API ๋กœ์ง ์ž‘์„ฑ์„ ์œ„ํ•ด Spring Rest Docs๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

OAuth

ํด๋ผ์ด์–ธํŠธ ์„œ๋ฒ„

๋กœ์ปฌ ๋กœํฌ์ธ ์™ธ์—๋„ ๊ฐ„ํŽธํ•œ ์ธ์ฆ ๋ฐฉ์‹ ์ œ๊ณต์„ ์œ„ํ•ด ๊ตฌ๊ธ€, ์นด์นด์˜ค, ๊นƒํ—ˆ๋ธŒ ๋กœ๊ทธ์ธ์„ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด์— ํด๋ผ์ด์–ธํŠธ๊ฐ€ OAuth ๋กœ๊ทธ์ธ์„ ์š”์ฒญํ•˜๋ฉด ์ธ์ฆ์„ ์œ„ํ•œ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ URI๋ฅผ ์ฃผ์—ˆ์ง€๋งŒ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฏธ๋ฆฌ URI๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋ฐ”๋กœ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ „๋‹ฌ ๋ฐ›์•„ ์ค‘๊ฐ„์— ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํ•˜๋Š” ๊ณผ์ •์„ ์ƒ๋žตํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฉ”์ผ ์ธ์ฆ & Redis

์ด๋ฉ”์ผ ์ „์†ก ๋ฐ ์ธ์ฆ ์ธ์ฆ๋œ ๊ฒฝ์šฐ

์ผ์‹œ์ ์œผ๋กœ ์ธ์ฆ๊ณผ ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํ‚ค, ๊ฐ’ ํ˜•ํƒœ์˜ ๋น„์ •ํ˜• ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ธ Redis ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž์˜ ์ด๋ฉ”์ผ์„ ํ‚ค๋กœ ํ•˜๊ณ  ์ธ์ฆ ์ƒํƒœ๋ฅผ ๊ฐ’์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ ํ›„์— ์ธ์ฆ ์ฝ”๋“œ ๋“ฑ์œผ๋กœ ์ธ์ฆ์— ์„ฑ๊ณตํ•œ ๊ฒฝ์šฐ ์ธ์ฆ ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ์‹์œผ๋กœ ์ผ์‹œ์ ์ธ ์ธ์ฆ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฒ€์ƒ‰๊ธฐ๋Šฅ (Mysql fulltext)

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ • ๋ฐ ์ธ๋ฑ์‹ฑ Full-Text Search

๊ธฐ์กด์˜ LIKE๋ฌธ์€ ์ฟผ๋ฆฌ๋Š” ๋ฌธ์ž์—ด ํŒจํ„ด ๋งค์นญ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋Œ€์šฉ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ฒฝ์šฐ์— ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ…์ŠคํŠธ ๊ฒ€์ƒ‰์— ํŠนํ™” ๋˜๊ณ  ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” MySQL์˜ Full-Text ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•œ๊ธ€ ๊ฒ€์ƒ‰์—๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋Š” n-gram parser๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ† ํฐ์˜ ๊ฐ’์„ 1๋กœ ์„ค์ •ํ•ด ์ธ๋ฑ์‹ฑ์„ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์†Œ ํ•œ ๊ธ€์ž์˜ ํ‚ค์›Œ๋“œ๋กœ๋„ ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

Querydsl

๊ธฐ๋ณธ์ ์ธ CRUD ๋Š” Spring Data JPA ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š” CRUD ๋ฉ”์„œ๋“œ ๋ฐ ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ GET ์š”์ฒญ์—์„œ ์›ํ•˜๋Š” ์กฐ๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์—ฌ๋Ÿฌ ์กฐ๊ฑด์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์ฟผ๋ฆฌ๋ฌธ์ด ๋ณต์žกํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ์— JPQL ์ด๋‚˜ Native Query ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ฟผ๋ฆฌ๋ฌธ์ด ๊ธธ์–ด์งˆ ๊ฒฝ์šฐ ์˜คํƒ€๋‚˜ ๋ฌธ๋ฒ•์ ์ธ ์˜ค๋ฅ˜ ๋“ฑ ํœด๋จผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ •์  ์ฟผ๋ฆฌ๊ฐ€ ์•„๋‹Œ ์ด์ƒ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Querydsl ์„ ๋ถ€๋ถ„์ ์œผ๋กœ ์‚ฌ์šฉํ–ˆ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์€ ์ด์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

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

git actions / Docker

gitactions

Job ๋ถ„๋ฆฌ

์ดˆ๊ธฐ git actions ๋Š” ํ•˜๋‚˜์˜ Job ์—์„œ ๋ชจ๋“  ๊ณผ์ •์„ ๋‹ค ์ฒ˜๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ…Œ์ŠคํŠธ๊ฐ€ ๋ฌด๊ฑฐ์›Œ์ง€๊ณ  ๊ทธ์— ๋”ฐ๋ผ ๋นŒ๋“œ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋ฉด์„œ ํ…Œ์ŠคํŠธ์™€ ๋นŒ๋“œ๋ฅผ ๋ถ„๋ฆฌํ•ด์•ผ๊ฒ ๋‹ค๋Š” ํŒ๋‹จ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. git actions ์˜ Job ์€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— test ๋ฅผ ํฌ๊ฒŒ 4๊ฐœ(testA, testB, testC, buildTest) ๋กœ ๋‚˜๋ˆ„๊ณ  ๊ฐ๊ฐ ์‹คํ–‰์‹œ์ผฐ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ ์‹œ์— API ๋ฌธ์„œํ™”๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ControllerTest ๋Š” ๋นŒ๋“œ Job ์—์„œ ํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ดํ›„ ๋ชจ๋“  ํ…Œ์ŠคํŠธ์™€ ๋นŒ๋“œ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด cd Job ์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น Job ์—์„œ ๋„์ปค๋ฅผ push ํ•˜๊ณ  EC2 ์—์„œ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์•„ ๋ฐฐํฌํ•˜๋Š” ๊ณผ์ •์ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

Caching

build.gradle ํŒŒ์ผ์€ ์ž์ฃผ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— actions/cache@v2 ์„ ํ†ตํ•ด ์˜์กด์„ฑ์„ ์บ์‹ฑํ•ด์ฃผ์–ด์„œ ํ…Œ์ŠคํŠธ ๋ฐ ๋นŒ๋“œ ์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œ์ผœ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๋„์ปค ์ด๋ฏธ์ง€ ์บ์‹ฑ์ด๋‚˜ ๋ ˆ์ด์–ด ์บ์‹ฑ์€ ์˜คํžˆ๋ ค ์บ์‹ฑ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์ €์žฅํ•˜๋Š” ๊ณผ์ •์ด ์‹œ๊ฐ„์ด ๋” ๊ฑธ๋ ค์„œ ์ƒ๋žตํ–ˆ์Šต๋‹ˆ๋‹ค.

Docker Image ์ตœ์ ํ™”

๋ฉ€ํ‹ฐ ์Šคํ…Œ์ด์ง€๋ฅผ ์ƒ๊ฐํ–ˆ์œผ๋‚˜ ์ด๋ฏธ git actions ์˜ Job ์—์„œ ๋นŒ๋“œ์™€ ๋ฐฐํฌ๊ฐ€ ๋ถ„๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ€ํ‹ฐ ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋Š” ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๋„์ปค ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด base-image ๋ฅผ openjdk:11-jre-slim ๋กœ ๋ณ€๊ฒฝํ–ˆ๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ build.gradle ์—์„œ ๋ถˆํ•„์š”ํ•œ dependency ๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

๊ฒฐ๊ณผ์ ์œผ๋กœ CICD ๊ณผ์ •์€ ํ‰๊ท  3๋ถ„ 20์ดˆ์—์„œ 2๋ถ„์œผ๋กœ ์ค„์˜€๊ณ , ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 731MB ์—์„œ 296MB ๋กœ 60% ์ค„์˜€์Šต๋‹ˆ๋‹ค.

๋นŒ๋“œ ์ตœ์ ํ™” ์ƒ์„ธ ๋‚ด์šฉ ํ™•์ธ โ˜ž CI/CD

๋กœ๊ทธ ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง

ec2 ๋ฐฐํฌ ์ดํ›„ ์ตœ์ดˆ ๋ช‡ ๋ฒˆ์˜ GET ์š”์ฒญ์€ 1000ms ์ด์ƒ์˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ๋‹ค๋Š” ๊ฑธ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฐฐํฌ ํ™˜๊ฒฝ๊ณผ ๋กœ์ปฌ ํ™˜๊ฒฝ๋„ ๋ถ„๋ช…ํžˆ ์ฐจ์ด๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€๋„ ๋ชจ๋‹ˆํ„ฐ๋ง์ด ๊ฐ€๋Šฅํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ๋กœ๊ทธ ์ „๋žต์„ ์„ธ์› ์Šต๋‹ˆ๋‹ค.

๋กœ๊ทธ ์ „๋žต

  • API ํ˜ธ์ถœ ์‹œ ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„
  • Repository ํด๋ž˜์Šค ํ˜ธ์ถœ ์‹œ ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„
  • ๋น„์ฆˆ๋‹ˆ์Šค ์˜ˆ์™ธ๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  Exception

๋กœ๊ทธ ํ™•์ธ

๋กœ๊ทธ๋Š” logBack ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. @Slf4j ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๋กœ๊ทธ๋ฅผ ํŒŒ์ผ๋กœ ๋‚จ๊ธฐ๋Š” ๊ฒŒ ๊ฐ„๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ SLF4J๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  Logback์„ ๊ทธ ๊ตฌํ˜„์ฒด๋กœ ์„ ํƒํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šคํ”„๋ง ๋‚ด๋ถ€์—์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ๋„ ํ•จ๊ป˜ ๋กœ๊ทธ๊ฐ€ ๋‚จ๋Š”๋‹ค๋Š” ์žฅ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

API ๋กœ๊ทธ๋Š” MDCLoggingFilter ์—์„œ, Data ์ ‘๊ทผ ๋กœ๊ทธ๋Š” RepositoryLoggingAop ์—์„œ, ์—๋Ÿฌ ๋กœ๊ทธ๋Š” GlobalExceptionHandler ์—์„œ ๋‚จ๊ฒผ์Šต๋‹ˆ๋‹ค. log.info ํ˜น์€ log.error ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด logs ํด๋”์— .log ํŒŒ์ผ๋กœ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๋กœ๊ทธ๋Š” ec2 ์—์„œ cloudwatch agent ์— ์˜ํ•ด ์ˆ˜์ง‘๋˜์–ด log group ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  metric ์„ ํ†ตํ•ด ํŒŒ์‹ฑํ•œ ํ›„ ํ•„์š”ํ•œ ๊ฐ’์€ ๋Œ€์‹œ๋ณด๋“œ์— ํ‘œ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค.

๋Œ€์‹œ๋ณด๋“œ ๋ฐ”๋กœ๊ฐ€๊ธฐ

ํŠนํžˆ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ํ†ตํ•ด GET ์š”์ฒญ์˜ ์‘๋‹ต ์‹œ๊ฐ„ ์ง€์—ฐ์€ ๋ฐฐํฌ ์‹œ๋งˆ๋‹ค ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์—ˆ๊ณ  ์•„๋ž˜์˜ warm up ์„ ํ•˜๊ฒŒ ๋˜๋Š” ์ด์œ ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

JVM warm up

warmup

warmup ์„ ํ•˜๊ฒŒ ๋œ ์ด์œ ๋Š” ์œ„ ๊ทธ๋ž˜ํ”„์™€ ๊ฐ™์ด ํŠน์ • ์š”์ฒญ์—์„œ 1000ms ์ด์ƒ์˜ ๋ ˆ์ดํ„ด์‹œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” GET ์š”์ฒญ์—์„œ ์ฟผ๋ฆฌ๋ฌธ์˜ ์กฐ๊ฑด์ด ๋งŽ์ด ๊ฑธ๋ ค์žˆ์–ด์„œ ๊ทธ๋Ÿฐ๊ฐ€ ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์‹ค์ œ๋กœ DB ์—์„œ ์ฟผ๋ฆฌ๋ฌธ ์‹คํ–‰ ์ž์ฒด๋Š” 10ms ์ด ์ฑ„ ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•ด๋ณธ ๊ฒฐ๊ณผ ์˜คํžˆ๋ ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ๋Œ€๋ถ€๋ถ„์˜ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ JVM ์˜ JIT(Just-in-Time) ์œผ๋กœ ์ธํ•ด ์ปดํŒŒ์ผ์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ์ตœ์ดˆ ๋ช‡ ๊ฐœ์˜ ์š”์ฒญ ์ดํ›„์—๋Š” ์ •์ƒ์ ์ธ ์‘๋‹ต ์‹œ๊ฐ„์„ ๋ฐ˜ํ™˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ฒ˜์Œ์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜๋ฉด์„œ localhost:8080 ์œผ๋กœ GET ์œ„์ฃผ์˜ ๋ฉ”์ธ API ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ warm up ๊ณผ์ •์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ warm up ๊ณผ์ •์ด 3๋ถ„ ์ด์ƒ ์†Œ์š”๋˜๋ฉด์„œ ๋ฉ”์ธ ๋กœ์ง ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ”๊พธ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์Šคํ”„๋ง์˜ ํ•„ํ„ฐ ๋ถ€๋ถ„๋„ warm up ํ•˜๊ธฐ ์œ„ํ•ด WarmupController ๋ฅผ ๋งŒ๋“ค์–ด ํ•ด๋‹น API ๋ฅผ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” warmup ์„ ํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

public class WarmupApi implements ApplicationListener<ContextRefreshedEvent> {

    ... 

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {

        if (warmup ์ด ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด) {
;
            request("http://localhost:8080/warmup"); //WarmupController ํ˜ธ์ถœ
            methodWarmup(); //๋ฉ”์„œ๋“œ ๋‹จ์œ„ warmup ์ˆ˜ํ–‰

            warmupState.setWarmupCompleted(true); //warmup ์„ ์™„๋ฃŒ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ
        }
    }

    private void methodWarmup() {

        videoMethodWarmup();
        channelMethodWarmup();
        memberMethodWarmup();
    }

    ...
}

ํ•ด๋‹น ๊ณผ์ •์„ ์™„๋ฃŒํ•˜๋ฉด ์ตœ์ดˆ ์š”์ฒญ ์‹œ์—๋„ ํ‰๊ท ์ ์ธ ์‘๋‹ต ์‹œ๊ฐ„ (200ms ~ 400ms) ์œผ๋กœ ์š”์ฒญ์ด ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

warm up ์ƒ์„ธ ๋‚ด์šฉ ํ™•์ธ โ˜ž warm up


๐Ÿ”จ ํ…Œ์ŠคํŠธ/๋ชจ๋‹ˆํ„ฐ๋ง

ํ…Œ์ŠคํŠธ/๋ชจ๋‹ˆํ„ฐ๋ง ํ™•์ธ (๐Ÿ‘ˆ Click)

๊ฐœ๋ฐœ์ž ํ…Œ์ŠคํŠธ

๊ฐœ๋ฐœ์ž ํ…Œ์ŠคํŠธ๋Š” ์š”๊ตฌ์‚ฌํ•ญ ๊ธฐ๋ฐ˜์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ์š”๊ตฌ์‚ฌํ•ญ์—๋Š” ์—†์ง€๋งŒ ํ•„์š”ํ•œ ๋‚ด์šฉ์ด๋‚˜ ์•„์ด๋””์–ด๋Š” ์Šคํฌ๋Ÿผ์„ ํ†ตํ•ด ํ…Œ์ŠคํŠธ ๋ฌธ์„œ์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ๋ถ€ํ„ฐ ๋ฐฐํฌ๊นŒ์ง€ ์ •๊ธฐ์ ์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ์œผ๋ฉฐ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

BE ๋‹จ์œ„ ๋ฐ ํ†ตํ•ฉํ…Œ์ŠคํŠธ

test

BE JAVA ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ด 800 ๊ฐœ์˜ ๋‹จ์œ„ ๋ฐ ํ†ตํ•ฉํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์˜ ๋Œ€์ƒ์€ Controller, Service, Repository, Entity ์˜ ๋ชจ๋“  public ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ์ค‘์ ์€ ๊ธฐ๋Šฅ ๋™์ž‘ ์—ฌ๋ถ€์™€ ์—ฃ์ง€ ์ผ€์ด์Šค์—์„œ ์ •์ƒ์ ์ธ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š”์ง€ ์˜€์Šต๋‹ˆ๋‹ค. ํ†ตํ•ฉํ…Œ์ŠคํŠธ๋Š” ์ฃผ์–ด์ง„ ์กฐ๊ฑด์—์„œ mockMvc ๋ฅผ ํ™œ์šฉํ•ด API ๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ๊ธฐ๋Œ€๋˜๋Š” ์‘๋‹ต๊ฐ’๊ณผ DB CRUD ๊ฐ€ ๋˜๋Š”์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ ํšŒ๊ณ 

ํšŒ๊ณ  ํ™•์ธ (๐Ÿ‘ˆ Click)

About

๐Ÿง‘โ€๐Ÿ’ป ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๊ธฐ ์œ„ํ•œ ์„ ํƒ, Prometheus

https://www.itprometheus.net/

License:MIT License


Languages

Language:Java 68.3%Language:JavaScript 22.6%Language:TypeScript 7.5%Language:HTML 0.9%Language:MDX 0.4%Language:CSS 0.3%Language:Vim Snippet 0.1%Language:Dockerfile 0.0%