Skip to content

briiiqtt/short-url

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

384 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

ShortURL

title:url shortener

๋‹จ์ถ• URL ์ƒ์„ฑ ๋ฐ ๋ฆฌ๋‹ค์ด๋ ‰์…˜ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

๋ชฉ์ฐจ

์‚ฌ์šฉ ๊ธฐ์ˆ 

์ปดํฌ๋„ŒํŠธ ๊ธฐ์ˆ ย ย  ๋น„๊ณ 
Backend Java 21, Spring Boot 3, Spring Data JPA, Flyway
Frontend React 19, Nginx
Cache DB ๋ถ€ํ•˜ ๊ฐ์†Œ์™€ ๋น ๋ฅธ ์‘๋‹ต์„ ์œ„ํ•ด Redis ์‚ฌ์šฉ
Database ํŠธ๋žœ์žญ์…”๋„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด PostgreSQL ์‚ฌ์šฉ
Gateway ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ์š”์ฒญ์„ ํ”„๋ก์‹œํ•˜๊ธฐ ์œ„ํ•ด Nginx ์‚ฌ์šฉ
Infrastructure ํ™˜๊ฒฝ ์ผ๊ด€์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์šฉ์ด์„ฑ, ๋ฆฌ์†Œ์Šค ๊ฒฉ๋ฆฌ๋ฅผ ์œ„ํ•ด Docker๋ฅผ ์‚ฌ์šฉ
OCI free tier ์ด์šฉ
ํ•ญ๋ชฉ ๋น„๊ณ 
์ธ์Šคํ„ด์Šค
โ€ƒOCI VM.Standard.E2.1.Micro
CPU 1/8 OCPU (8์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณต์œ ํ•˜๋Š” 1์ฝ”์–ด)
RAM 1GB
Swap 2GiB

์ฃผ์š” ๊ธฐ๋Šฅ

  • ๋‹จ์ถ• URL ์ƒ์„ฑ: URL์„ ์ž…๋ ฅํ•˜๋ฉด ๊ฐ™์€ ๋ชฉ์ ์ง€๋ฅผ ํ–ฅํ•˜๋Š” ์งง์€ URL์„ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ๊ฐ™์€ URL์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋‹จ์ถ• URL์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • URL ๋ฆฌ๋‹ค์ด๋ ‰์…˜: ๋‹จ์ถ• URL๋กœ ๋“ค์–ด์˜ค๋Š” GET ์š”์ฒญ์„ ์›๋ณธ URL๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•ฉ๋‹ˆ๋‹ค.

  • ๋‹จ์ถ• URL ๋ชจ์•„๋ณด๊ธฐ: Google/Naver OAuth2๋ฅผ ํ†ตํ•ด ํšŒ์›์œผ๋กœ ๋กœ๊ทธ์ธํ•˜๋ฉด ์ƒ์„ฑํ–ˆ๋˜ ๋‹จ์ถ• URL์„ ๋ชจ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

service architecture

๊ฐ ๋…ธ๋“œ์˜ ์—ญํ• 

  1. ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„œ๋ฒ„: ๋ธŒ๋ผ์šฐ์ €์˜ HTTPS ์š”์ฒญ์„ ๋ณตํ˜ธํ™”ํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด ์„œ๋ฒ„๋กœ ํ”„๋ก์‹œํ•ฉ๋‹ˆ๋‹ค. ์†Œ์Šค๋Š” ๋ณ„๋„์˜ reposiory ์— ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ๊ฒŒ์ดํŠธ์›จ์ด ์„œ๋ฒ„: ์š”์ฒญ ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ์š”์ฒญ์„ ๋‚ด๋ถ€ ์„œ๋ฒ„๋กœ ํ”„๋ก์‹œํ•ฉ๋‹ˆ๋‹ค.
  3. ํ”„๋ก ํŠธ์—”๋“œ ์„œ๋ฒ„: React๋กœ ๊ตฌ์„ฑ๋œ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์ •์  ํŒŒ์ผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ฐฑ์—”๋“œ ์„œ๋ฒ„: ๊ฒŒ์ดํŠธ์›จ์ด ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์š”์ฒญ์„ ํ”„๋ก์‹œ๋ฐ›๊ณ  ์ด๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์š”์ฒญ ํ๋ฆ„

๋‹จ์ถ• URL ์ƒ์„ฑ

  1. ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ํ†ตํ•ด ํ”„๋ก ํŠธ์—”๋“œ์— ์š”์ฒญํ•˜์—ฌ ์‘๋‹ต์„ ๋ฐ›๊ณ  ํ™”๋ฉด์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ธŒ๋ผ์šฐ์ €๋Š” ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’์„ ๋ฐ›์•„ {frontendUrl}/api๋กœ POST /api/shorten ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , ์ด๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์— ์˜ํ•ด ๋ฐฑ์—”๋“œ๋กœ ํ”„๋ก์‹œ๋ฉ๋‹ˆ๋‹ค.
  3. ๋ฐฑ์—”๋“œ๋Š” ์š”์ฒญ์„ ์ „๋‹ฌ๋ฐ›๊ณ  ๋‹จ์ถ•URL์˜ ๊ฒฝ๋กœ๊ฐ€ ๋  ID๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ทธ ID๋ฅผ Unique Key๋กœ ํ•˜์—ฌ DB์— ์ €์žฅ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
  4. ์ €์žฅ์— ์„ฑ๊ณตํ•˜๋ฉด ์ƒ์„ฑ๋œ ID ์•ž์— baseUrl์„ ๋ถ™์—ฌ ๋‹จ์ถ•URL์„ ์™„์„ฑํ•˜๊ณ  ์‘๋‹ต์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  5. ๋ธŒ๋ผ์šฐ์ €๋Š” ์‘๋‹ต ๋ฐ›์€ shortenedUrl์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋‹จ์ถ• URL ์กฐํšŒ

  1. ์‚ฌ์šฉ์ž๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋‹จ์ถ• URL๋กœ ์ ‘์†ํ•จ์œผ๋กœ์จ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๊ฑฐ์ณ Backend๋กœ GET /{Base62EncodedKey} ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  2. Backend์—์„œ๋Š” ๋จผ์ € Redis ์บ์‹œ์—์„œ ํ•ด๋‹น ๊ฐ’์„ ์ฐพ๊ณ , Cache Miss์˜ ๊ฒฝ์šฐ DB๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
  3. ๋งŒ์•ฝ DB์—์„œ ๊ฐ’์„ ์ฐพ์•˜๋‹ค๋ฉด ํ•ด๋‹น ๊ฐ’์„ Redis์— ์บ์‹ฑํ•˜๊ณ , ์›๋ณธ URL์„ ํ–ฅํ•ด 302 Found ์ƒํƒœ ์ฝ”๋“œ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•ฉ๋‹ˆ๋‹ค.
  4. ๋งŒ์•ฝ DB์—๋„ ์ฐพ๋Š” ๊ฐ’์ด ์—†๋‹ค๋ฉด 404 Not Found ์ƒํƒœ ์ฝ”๋“œ๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.
  5. ๋ธŒ๋ผ์šฐ์ €๋Š” ์‘๋‹ต์— ๋”ฐ๋ผ ์›๋ณธ URL๋กœ ์ ‘์†ํ•˜๊ฑฐ๋‚˜ 404 ํŽ˜์ด์ง€๋ฅผ ๋„์›๋‹ˆ๋‹ค.

์‹คํ–‰, ๋ฐฐํฌ ๋ฐฉ๋ฒ•

๊ฐœ๋ฐœ(๋กœ์ปฌ)ํ™˜๊ฒฝ

ํ˜ธ์ŠคํŠธ๋ฅผ ํ–ฅํ•˜๋Š” ๋„๋ฉ”์ธ์ด ์žˆ์„ ๊ฒƒ์„ ์ „์ œ๋กœ ํ”„๋กœ์ ํŠธ๊ฐ€ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. hosts ํŒŒ์ผ์„ ์ ์ ˆํžˆ ์ˆ˜์ •ํ•˜์‹œ๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. compose.dev.yml์— ํ•ด๋‹น ๋‚ด์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

.env.example์„ ์ฐธ๊ณ ํ•˜์—ฌ .env.development๋ฅผ ์ž‘์„ฑํ•œ ํ›„ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

docker compose -f compose.yml -f compose.dev.yml --env-file .env.development up -d --build

backend๋Š” recompile์‹œ ํ•ซ๋ฆฌ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. (๋ฐ”์ธ๋“œ๋งˆ์šดํŠธ+springBootDevtools+bootRun)
frontend๋Š” ํŒŒ์ผ ์ €์žฅ์‹œ ํ•ซ๋ฆฌ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. (๋ฐ”์ธ๋“œ๋งˆ์šดํŠธ+next dev)

๋ฐฐํฌํ™˜๊ฒฝ

์ด repository์—๋Š” ๋ฆฌ๋ฒ„์Šคํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฑธ ๋ฐฐํฌํ•˜๋ ค๋ฉด gateway์˜ ์„ค์ •์„ ์ ์ ˆํžˆ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๋ฆฌ๋ฒ„์Šคํ”„๋ก์‹œ ์„œ๋ฒ„๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์šด์˜ ํ™˜๊ฒฝ๊ฐ’์€ .env.production ํŒŒ์ผ๋กœ ๋ฐฐํฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. GitHub Actions์˜ Variables์™€ Secrets์— ๋“ฑ๋กํ•˜๊ณ , Compose๋Š” ๋ฐฐํฌ ์‹œ์ ์˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜์—์„œ ๊ฐ’์„ ์ฝ์Šต๋‹ˆ๋‹ค.

GitHub Actions Variables์— ๋“ฑ๋กํ•  ๊ฐ’:

  • SPRING_PROFILES_ACTIVE
  • SPRING_KAFKA_BOOTSTRAP_SERVERS
  • APP_SHORTEN_BASE_URL
  • APP_FRONTEND_URL
  • APP_ROOT_DOMAIN
  • APP_COOKIE_DOMAIN
  • APP_LOG_LEVEL
  • TOSS_PAYMENTS_CLIENT_KEY
  • TOSS_PAYMENTS_WEBHOOK_PAYMENT_VERIFICATION_ENABLED
  • BILLING_PRO_FREE_START_ENABLED
  • BILLING_PRO_FREE_START_DURATION_DAYS
  • BILLING_RECURRING_ENABLED
  • BILLING_RECURRING_CRON
  • NGINX_BACKEND_HOST
  • NGINX_FRONTEND_HOST
  • NEXT_PUBLIC_SITE_URL
  • TZ

GitHub Actions Secrets์— ๋“ฑ๋กํ•  ๊ฐ’:

  • SPRING_DATASOURCE_URL
  • SPRING_DATASOURCE_USERNAME
  • SPRING_DATASOURCE_PASSWORD
  • JWT_SECRET
  • VISITOR_KEY_SECRET
  • SPRING_OAUTH_GOOGLE_CLIENT_ID
  • SPRING_OAUTH_GOOGLE_CLIENT_SECRET
  • SPRING_OAUTH_NAVER_CLIENT_ID
  • SPRING_OAUTH_NAVER_CLIENT_SECRET
  • TOSS_PAYMENTS_SECRET_KEY
  • TOSS_PAYMENTS_WEBHOOK_SECRET
  • BILLING_ENCRYPTION_KEY
  • HOST_ARM1
  • HOST_AMD1
  • SSH_KEY

DB ์„œ๋น„์Šค๋ฅผ ํฌํ•จํ•ด ์šด์˜ Compose๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋Š” ๋‹ค์Œ ๊ฐ’๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. compose.arm2.yml๋กœ DB ์„œ๋ฒ„๋ฅผ ๋ณ„๋„ ๋ฐฐํฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋™์ผํ•˜๊ฒŒ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

  • POSTGRES_USER
  • POSTGRES_PASSWORD
  • POSTGRES_DB
  • HOST_ARM2

์ˆ˜๋™์œผ๋กœ ์šด์˜ Compose๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ .env.production ํŒŒ์ผ์„ ๋งŒ๋“ค์ง€ ์•Š๊ณ , ์œ„ ๋ชฉ๋ก์˜ ํ•„์ˆ˜ ๊ฐ’์„ ์‰˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ์ฃผ์ž…ํ•œ ๋’ค ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ•„์ˆ˜ ๊ฐ’์ด ๋น ์ง€๋ฉด Compose๊ฐ€ ์‹œ์ž‘ ์ „์— ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

local > export SPRING_DATASOURCE_URL=...
local > export SPRING_DATASOURCE_USERNAME=...
local > export SPRING_DATASOURCE_PASSWORD=...
local > export NEXT_PUBLIC_SITE_URL=https://linkpado.com
local > export NGINX_BACKEND_HOST=pado.cc
local > export NGINX_FRONTEND_HOST=linkpado.com
local > export ...
local > docker compose -f compose.yml -f compose.prod.yml build
local > docker compose -f compose.yml -f compose.prod.yml push

remote > export SPRING_DATASOURCE_URL=...
remote > export SPRING_DATASOURCE_USERNAME=...
remote > export SPRING_DATASOURCE_PASSWORD=...
remote > export NEXT_PUBLIC_SITE_URL=https://linkpado.com
remote > export NGINX_BACKEND_HOST=pado.cc
remote > export NGINX_FRONTEND_HOST=linkpado.com
remote > export ...
remote > docker compose -f compose.yml -f compose.prod.yml pull
remote > docker compose -f compose.yml -f compose.prod.yml up -d --no-build

tl;pr (Too Long; Please Read)

ํ•™์Šต ์„ฑ๊ณผ

์˜์—ญ ์‚ฌ์šฉ ๊ธฐ์ˆ  ์„ฑ๊ณผ ๋ฐ ๊ฒฝํ—˜
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ Spring Boot 3 Java 21์„ ํ™œ์šฉํ•œ ๋ฐฑ์—”๋“œ ํ™˜๊ฒฝ ๊ตฌ์ถ•
@Transactional์˜ ํ”„๋ก์‹œ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ  ๋‚™๊ด€์  ๋ฝ์˜ ์žฌ์‹œ๋„ ์ ˆ์ฐจ ๊ตฌํ˜„
์ธ์ฆ/์ธ๊ฐ€ Spring Security, JWT, OAuth2 Google/Naver OAuth2๋ฅผ ์ด์šฉํ•œ ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ตฌํ˜„
JWT ๋„์ž…์„ ํ†ตํ•œ Statelessํ•œ ์ธ์ฆ ์‹œ์Šคํ…œ ๊ตฌ์ถ•
์ธํ”„๋ผ/๋„คํŠธ์›Œํฌ Docker, Nginx, OCI ๊ณ„์ธตํ˜• ๋„คํŠธ์›Œํฌ ๊ตฌ์กฐ ์„ค๊ณ„๋กœ ๋ณด์•ˆ์„ฑ ๋†’์€ ์ธํ”„๋ผ ๊ตฌ์ถ•
Rate limit์„ ์ ์šฉํ•˜์—ฌ ํŠธ๋ž˜ํ”ฝ ์•ˆ์ •์„ฑ ํ™•๋ฆฝ
์บ์‹œ Redis ์„œ๋น„์Šค ํŠน์„ฑ์„ ๊ณ ๋ คํ•œ ์ „๋žต์  ์บ์‹œ ๋„์ž…์œผ๋กœ ์„ฑ๋Šฅ ํ–ฅ์ƒ
ํ…Œ์ŠคํŠธ JUnit ๊ฒฐํ•จ์„ ์กฐ๊ธฐ๋ฐœ๊ฒฌํ•˜๊ณ  ์•ˆ์ •์  ๋ฆฌํŒฉํ† ๋ง ํ™˜๊ฒฝ ์กฐ์„ฑ

๋ฐฑ์—”๋“œ ์ปจ๋ฒค์…˜

์ปจ๋ฒค์…˜์— ๋Œ€ํ•ด backend/README.md์— ์ƒ์„ธํ•œ ๋‚ด์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ์ถ• URL ์ƒ์„ฑ ์ „๋žต

7์ž๋ฆฌ Base58 ๋ฌธ์ž์…‹์˜ ๋ฌธ์ž์—ด

๋‹จ์ถ• URL์˜ ๊ฒฝ๋กœ๋Š” 123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ์˜ ๋ฌธ์ž์—ด ์ค‘ SecureRandom์œผ๋กœ ๋ฌด์ž‘์œ„ ์ž๋ฆฟ์ˆ˜๋ฅผ ๋ฝ‘์€ ๋ฌธ์ž 7๊ฐœ๋กœ ๊ตฌ์„ฑ๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

์ด ๋ฐฉ์‹์„ ์„ ํƒํ•จ์œผ๋กœ์จ ์•„๋ž˜ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

  1. ์‰ฝ๊ณ  ์งง์œผ๋ฉด์„œ, ๋งŽ์•„์•ผ ํ•œ๋‹ค.

    • ๋‹จ์ถ• URL์€ ์‚ฌ๋žŒ์ด ์ง์ ‘ ํƒ€์ดํ•‘ํ•˜๊ธฐ ์‰ฌ์›Œ์•ผํ•ฉ๋‹ˆ๋‹ค. ๋น„์Šทํ•˜๊ฒŒ ์ƒ๊ธด O์™€ 0, I์™€ L, ํƒ€์ดํ•‘ํ•˜๊ธฐ ๋ถˆํŽธํ•œ ํŠน์ˆ˜๋ฌธ์ž๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์€ Base58 ๋ฌธ์ž์…‹์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ์ฃผ์†Œ๋ฅผ ์งง๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด 7์ž๋ฆฌ๋งŒ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ 58์ง„๋ฒ•์œผ๋กœ ์ถฉ๋ถ„ํžˆ ๋งŽ์€ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. /
  2. ์˜ˆ์ธกํ•  ์ˆ˜ ์—†์–ด์•ผ ํ•œ๋‹ค.

    • ์ˆœ์ฐจ๊ฐ€ ์•„๋‹Œ ๋žœ๋ค์ด๊ธฐ์— ์˜ˆ์ธกํ•˜๊ธฐ ๋งค์šฐ ์–ด๋ ค์›Œ ๋ณด์•ˆ์— ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  3. ๋™์‹œ์„ฑ ๋ฌธ์ œ

    • ๋žœ๋คํ•œ ๊ฐ’์„ ์ƒ์„ฑ ํ›„ ์ผ๋‹จ ์ €์žฅ์„ ์‹œ๋„ํ•˜๊ณ , ์ค‘๋ณต์ด๋ฉด @Retryable์„ ํ†ตํ•ด 5ํšŒ๊นŒ์ง€ ์žฌ์‹œ๋„ํ•˜๋Š” ๋‚™๊ด€์  ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์—, Race Condition์ด๋‚˜ Deadlock์—์„œ ๋น„๊ต์  ์ž์œ ๋กญ์Šต๋‹ˆ๋‹ค.
    • ๋ถ„์‚ฐํ™˜๊ฒฝ์—์„œ๋„ ๊ฐ ์„œ๋ฒ„๊ฐ„์˜ ๋ณต์žกํ•œ ๋™๊ธฐํ™” ๊ณผ์ •์ด ํ•„์š”์—†์–ด ๋ถ„์‚ฐํ™˜๊ฒฝ ์นœํ™”์ ์ž…๋‹ˆ๋‹ค.
  4. ํ™•์žฅ์„ฑ
    ๊ทธ๋Ÿด ์ผ์ด ์—†๊ฒ ์ง€๋งŒ, ๊ฒฝ๋กœ์— ์“ธ id๊ฐ€ ๊ณ ๊ฐˆ๋˜๋Š” ๊ฒฝ์šฐ id๋ฅผ ๋‹จ ํ•œ ์ž๋ฆฌ๋งŒ ๋” ๋Š˜๋ ค๋„ ์—„์ฒญ๋‚œ ํ™•์žฅ์„ฑ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

Redis ์บ์‹œ ๊ตฌ์„ฑ์— ๋”ฐ๋ฅธ ์„ฑ๋Šฅ ํ–ฅ์ƒ๊ณผ ์บ์‹œ ์ „๋žต

๋‹จ์ถ• URL ์„œ๋น„์Šค๋Š” ์“ฐ๊ธฐ ์ž‘์—…๋ณด๋‹ค ์ฝ๊ธฐ ์ž‘์—…์ด ํ›จ์”ฌ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ตœ๊ทผ์— ์ƒ์„ฑ ๋˜๋Š” ์กฐํšŒ๋œ URL์ผ ์ˆ˜๋ก ๋‹ค์‹œ ์กฐํšŒ๋  ํ™•๋ฅ ์ด ๋†’์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋งค๋ฒˆ RDB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฟผ๋ฆฌํ•ด์˜ค๋Š” ๊ฒƒ๋ณด๋‹ค, ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜ ์บ์‹ฑ์„ ํ™œ์šฉํ•ด ์‘๋‹ต ์†๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  DB์˜ IO ๋ณ‘๋ชฉ์„ ๋ฐฉ์ง€ํ•˜๋ ค๋Š” ๋ชฉ์ ์œผ๋กœ redis ์บ์‹œ๋ฅผ ๊ตฌ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์‘๋‹ต์†๋„(P95, P99) ๊ฐœ์„ 

30RPS ์‘๋‹ต์‹œ๊ฐ„ ์บ์‹œ ์—†์Œ ์บ์‹œ ๊ตฌ์ถ• ํ›„ ๊ฐœ์„ ์œจ
p(95) 262.51ms 44.04ms ์•ฝ 83% ๊ฐœ์„ 
p(99) 1.05s 68.07ms ์•ฝ 93% ๊ฐœ์„ 
ํ‰๊ท  65.92ms 8.32ms ์•ฝ 87% ๊ฐœ์„ 

๋ถ€ํ•˜ํ…Œ์ŠคํŠธ๋Š” k6์œผ๋กœ ์ง„ํ–‰ํ•˜์˜€์œผ๋ฉฐ, RPS๋Š” ์š”์ฒญ ์‹คํŒจ์œจ 0%๋ฅผ ์œ ์ง€ํ•˜๋Š” ์ตœ๊ณ  ๋ถ€ํ•˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹จ์ถ•URL์„ ์บ์‹œ์—์„œ ์ฝ์„ ๋•Œ๋Š” Look aside ์ „๋žต์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋จผ์ € Redis๋ฅผ ์กฐํšŒ ํ›„, ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด DB์—์„œ ์ฝ์–ด Redis์— ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค.

  • ๋‹จ์ถ•URL์„ ์บ์‹œ์— ์“ธ ๋•Œ๋Š” Write around ์ „๋žต์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋‹จ์ถ•URL ์กฐํšŒ์‹œ์— ์บ์‹œ์— ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค. ์ƒ์„ฑ๋งŒ ํ•ด๋†“๊ณ  ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋‹จ์ถ•URL์ด ์บ์‹œ๋ฅผ ๋‚ญ๋น„์‹œํ‚ค๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

  • ๋‹จ์ถ•URL์„ ์บ์‹œ์—์„œ ์ œ๊ฑฐํ•  ๋•Œ๋Š” TTL(Time To Live) + LRU(Least Recently Used) ์ „๋žต์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์บ์‹œ์˜ ๊ธฐ๋ณธ์ ์ธ ์ˆ˜๋ช…์„ ์žก๊ณ , ์กฐํšŒ๋  ๋•Œ๋งˆ๋‹ค ์ˆ˜๋ช…์„ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์บ์‹œ๊ฐ€ ๊ฐ€๋“ ์ฐผ์„ ๋•Œ๋Š” ๋งˆ์ง€๋ง‰ ์กฐํšŒ๊ฐ€ ์˜ค๋ž˜๋œ ์ˆœ์œผ๋กœ ์บ์‹œ์—์„œ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๋ฆฌ๋‹ค์ด๋ ‰์…˜์„ 301์ด ์•„๋‹Œ 302๋กœ ํ•˜๋Š” ์ด์œ 

301 Moved Permanently๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ทธ ๋ฆฌ๋‹ค์ด๋ ‰์…˜์„ ์บ์‹ฑํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„์—๋Š” ๊ฐ™์€ ์š”์ฒญ์„ ๋ฐ˜๋ณตํ•  ๋•Œ, ์„œ๋ฒ„๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ์บ์‹ฑ๋œ ๋ฆฌ๋‹ค์ด๋ ‰์…˜ ๋ชฉ์ ์ง€๋กœ ๊ฐ‘๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๊ฑด ์กฐํšŒ์ˆ˜๋‚˜ ์ง€์—ญ ๋“ฑ ๋ฐฉ๋ฌธ ๋ฐ์ดํ„ฐ ์ง‘๊ณ„์— ์ฐจ์งˆ์„ ์ค๋‹ˆ๋‹ค.

302 Found๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ์บ์‹ฑ์—†์ด ํ•ญ์ƒ ์ด ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. 301๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ์„œ๋น„์Šค๋Š” ์ถ”ํ›„ ํšŒ์›์—๊ฒŒ ๋ฐฉ๋ฌธ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•  ์˜ˆ์ •์ด๊ธฐ์— 301์ด ์•„๋‹Œ 302๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ณ„์ธตํ˜• ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ํ•œ ์ด์œ 

์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์ด ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋กœ ๋„๋‹ฌํ•˜๊ธฐ๊นŒ์ง€ ๋ฆฌ๋ฒ„์Šคํ”„๋ก์‹œ-๊ฒŒ์ดํŠธ์›จ์ด-๋ฐฑ์—”๋“œ์„œ๋ฒ„ ๋ฅผ ๊ฑฐ์น˜๋Š” ๊ณ„์ธตํ˜• ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ํŠน์ง•์„ ์ง€๋‹™๋‹ˆ๋‹ค.

  • ๊ณต๊ฒฉํ‘œ๋ฉด ์ตœ์†Œํ™”: ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ์™€ ๋งž๋‹ฟ๋Š” ์ง€์ ์„ ์ตœ์ „๋ฐฉ์˜ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„œ๋ฒ„๋งŒ์œผ๋กœ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค. WAS์™€ DB ๋“ฑ์€ ํ”„๋ผ์ด๋น— ๋„คํŠธ์›Œํฌ์— ๊ฒฉ๋ฆฌํ•˜์—ฌ ๋ณด์•ˆ ์œ„ํ˜‘์„ ์ตœ์†Œํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ธํ”„๋ผ ํ™•์žฅ์„ฑยท์œ ์—ฐ์„ฑ: ์„œ๋ฒ„๋ฅผ ์ˆ˜ํ‰ํ™•์žฅํ•˜๋ ค ํ•  ๊ฒฝ์šฐ, weight ๋“ฑ ๊ฒŒ์ดํŠธ์›จ์ด ์„ค์ •๋งŒ์œผ๋กœ ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. split_clients ๋“ฑ ์„ค์ •์„ ํ†ตํ•ด ์นด๋‚˜๋ฆฌ ๋ฐฐํฌ ๋“ฑ ์œ ์—ฐํ•œ ํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.
  • SSL ์ข…๋‹จ์  ์ผ์›ํ™”: SSL ์ธ์ฆ์„œ ๊ด€๋ฆฌ์™€ HTTPS ๋ณตํ˜ธํ™”๋ฅผ ์ตœ์ „๋ฐฉ์˜ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ ์ „๋‹ดํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ ๋‚ด๋ถ€ ์„œ๋ฒ„๋“ค์€ SSL ์„ค์ •๊ณผ ๋ณตํ˜ธํ™” ์—ฐ์‚ฐ์ด ๋ถˆํ•„์š”ํ•ด์ง‘๋‹ˆ๋‹ค.
  • CORS ํ•ด๊ฒฐ: ๋ธŒ๋ผ์šฐ์ € ์ž…์žฅ์—์„œ ๋ชจ๋“  ์š”์ฒญ๊ณผ ์‘๋‹ต์ด ๋™์ผํ•œ origin๊ณผ ์ด๋ฃจ์–ด์ง€๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ฐธ์กฐ

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages