Skip to content

Repository files navigation

Notification System

Spring Boot 기반 μ‹œμŠ€ν…œ 섀계 ν”„λ‘œμ νŠΈλ₯Ό λΉ λ₯΄κ²Œ μ‹œμž‘ν•˜κ³ , λΆ€ν•˜ ν…ŒμŠ€νŠΈμ™€ λͺ¨λ‹ˆν„°λ§μ„ 톡해 섀계 선택을 κ²€μ¦ν•˜κΈ° μœ„ν•œ 곡톡 ν…œν”Œλ¦Ώμž…λ‹ˆλ‹€.

μƒˆλ‘œμš΄ μ‹œμŠ€ν…œ 섀계 주제λ₯Ό μ§„ν–‰ν•  λ•Œ 이 Repositoryλ₯Ό 기반으둜 λ³„λ„μ˜ Repositoryλ₯Ό μƒμ„±ν•˜κ³ , ν”„λ‘œμ νŠΈλ³„λ‘œ ν•„μš”ν•œ λ°μ΄ν„°λ² μ΄μŠ€, μΊμ‹œ, λ©”μ‹œμ§€ 브둜컀 등을 μΆ”κ°€ν•©λ‹ˆλ‹€.

λͺ©ν‘œ

  • 곡톡 Spring Boot μ‹€ν–‰ ν™˜κ²½ 제곡
  • Docker Compose 기반 둜컬 μ‹€ν—˜ ν™˜κ²½ 제곡
  • k6 기반 λΆ€ν•˜ ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€ 제곡
  • Prometheus와 Grafana 기반 λ©”νŠΈλ¦­ κ΄€μΈ‘
  • 섀계 및 μ‹€ν—˜ 과정을 λ™μΌν•œ λ¬Έμ„œ ν˜•μ‹μœΌλ‘œ 기둝
  • Platform Thread와 Virtual Thread 비ꡐ ν™˜κ²½ 제곡

기술 μŠ€νƒ

ꡬ뢄 기술
Language Java 25
Framework Spring Boot 4.1
Build Gradle
API Spring MVC
Metrics Spring Boot Actuator, Micrometer
Load Test k6
Monitoring Prometheus, Grafana
Container Docker, Docker Compose

Java 25 선택 이유

Java 25λŠ” 가상 μŠ€λ ˆλ“œκ°€ 정식 κΈ°λŠ₯으둜 제곡된 Java 21 μ΄ν›„μ˜ κ°œμ„  사항을 ν¬ν•¨ν•˜λŠ” LTS λ²„μ „μž…λ‹ˆλ‹€.

μ‹œμŠ€ν…œ 섀계 ν”„λ‘œμ νŠΈμ—μ„œλŠ” λ°μ΄ν„°λ² μ΄μŠ€, Redis, λ©”μ‹œμ§€ 브둜컀, μ™ΈλΆ€ API처럼 λΈ”λ‘œν‚Ή I/Oκ°€ 자주 λ°œμƒν•©λ‹ˆλ‹€. λ”°λΌμ„œ 동기식 Spring MVC ꡬ쑰λ₯Ό μœ μ§€ν•˜λ©΄μ„œ Platform Thread와 Virtual Thread의 λ™μ‹œ 처리 μ„±λŠ₯을 λΉ„κ΅ν•˜κΈ° μœ„ν•΄ Java 25λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

가상 μŠ€λ ˆλ“œλŠ” 기본적으둜 λΉ„ν™œμ„±ν™”λ˜μ–΄ 있으며 ν™˜κ²½λ³€μˆ˜λ‘œ μ „ν™˜ν•©λ‹ˆλ‹€.

VIRTUAL_THREADS_ENABLED=false

μ‹€μ œ λΈ”λ‘œν‚Ή I/Oκ°€ ν¬ν•¨λœ ν”„λ‘œμ νŠΈμ—μ„œλŠ” λ™μΌν•œ k6 μ‹œλ‚˜λ¦¬μ˜€λ‘œ λ‹€μŒ μ‹€ν—˜μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

μ‹€ν—˜ A: Java 25 + Platform Thread
μ‹€ν—˜ B: Java 25 + Virtual Thread

비ꡐ μ§€ν‘œ:

  • RPS
  • p95 및 p99 응닡 μ‹œκ°„
  • 였λ₯˜μœ¨
  • CPU μ‚¬μš©λ₯ 
  • JVM Heap
  • ν™œμ„± μŠ€λ ˆλ“œ 수
  • DB Connection Pool λŒ€κΈ°

전체 ꡬ쑰

flowchart LR
    K6[k6]
    APP[Spring Boot]
    ACTUATOR[Actuator / Micrometer]
    PROMETHEUS[Prometheus]
    GRAFANA[Grafana]

    K6 -->|HTTP Load| APP
    APP --> ACTUATOR
    PROMETHEUS -->|Scrape| ACTUATOR
    GRAFANA -->|PromQL| PROMETHEUS
Loading

디렉터리 ꡬ쑰

.
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ main
β”‚   └── test
β”œβ”€β”€ k6
β”‚   β”œβ”€β”€ smoke-test.js
β”‚   β”œβ”€β”€ load-test.js
β”‚   └── stress-test.js
β”œβ”€β”€ monitoring
β”‚   β”œβ”€β”€ prometheus
β”‚   β”‚   └── prometheus.yml
β”‚   └── grafana
β”‚       β”œβ”€β”€ dashboards
β”‚       └── provisioning
β”œβ”€β”€ docs
β”‚   β”œβ”€β”€ 01-requirements.md
β”‚   β”œβ”€β”€ 02-capacity-estimation.md
β”‚   β”œβ”€β”€ 03-architecture.md
β”‚   β”œβ”€β”€ 04-experiment.md
β”‚   └── 05-retrospective.md
β”œβ”€β”€ scripts
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ docker-compose.yml
└── README.md

제곡 API

Ping

μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰ 여뢀와 κΈ°λ³Έ HTTP λ©”νŠΈλ¦­μ„ ν™•μΈν•˜κΈ° μœ„ν•œ APIμž…λ‹ˆλ‹€.

GET /api/v1/ping

응닡:

{
  "message": "pong"
}

μ‹€ν–‰ μ „ μš”κ΅¬μ‚¬ν•­

  • Docker Desktop
  • Docker Compose v2
  • Java 25
  • Python 3
  • Git

Docker Composeλ₯Ό μ‚¬μš©ν•˜λ©΄ 둜컬 Java와 Gradle이 없어도 전체 ν™˜κ²½μ„ μ‹€ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μƒˆ ν”„λ‘œμ νŠΈ μ‹œμž‘ν•˜κΈ°

GitHub의 Use this template둜 Repositoryλ₯Ό μƒμ„±ν•œ λ’€ Cloneν•©λ‹ˆλ‹€.

./scripts/init-project.sh \
  url-shortener \
  com.backendsystemdesignlab.urlshortener \
  "URL Shortener"

μ‹€ν–‰ 방법

1. ν™˜κ²½λ³€μˆ˜ 파일 생성

cp .env.example .env

κΈ°λ³Έ μ„€μ •:

APP_NAME=notification-system

APP_PORT=8080
PROMETHEUS_PORT=9090
GRAFANA_PORT=3000

GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=admin

VIRTUAL_THREADS_ENABLED=false

κΈ°λ³Έ Grafana 계정은 둜컬 μ‹€ν—˜μš©μž…λ‹ˆλ‹€. μ™ΈλΆ€ ν™˜κ²½μ—μ„œλŠ” λ°˜λ“œμ‹œ λ³€κ²½ν•΄μ•Ό ν•©λ‹ˆλ‹€.

2. 전체 ν™˜κ²½ μ‹€ν–‰

./scripts/start.sh

직접 μ‹€ν–‰ν•˜λ €λ©΄:

docker compose up --build -d

3. μ‹€ν–‰ μƒνƒœ 확인

docker compose ps

Spring Boot μ»¨ν…Œμ΄λ„ˆκ°€ λ‹€μŒ μƒνƒœμ—¬μ•Ό ν•©λ‹ˆλ‹€.

healthy

4. μ„œλΉ„μŠ€ 접속

μ„œλΉ„μŠ€ μ£Όμ†Œ
Spring Boot http://localhost:8080
Health Check http://localhost:8080/actuator/health
Prometheus Metrics http://localhost:8080/actuator/prometheus
Prometheus http://localhost:9090
Grafana http://localhost:3000

Grafana κΈ°λ³Έ 계정:

ID: admin
Password: admin

λΆ€ν•˜ ν…ŒμŠ€νŠΈ

k6λŠ” μƒμ‹œ μ‹€ν–‰ν•˜μ§€ μ•Šκ³  ν…ŒμŠ€νŠΈ μ‹œ μΌνšŒμ„± μ»¨ν…Œμ΄λ„ˆλ‘œ μ‹€ν–‰λ©λ‹ˆλ‹€.

Smoke Test

APIκ°€ 기본적으둜 정상 λ™μž‘ν•˜λŠ”μ§€ κ²€μ¦ν•©λ‹ˆλ‹€.

./scripts/run-smoke-test.sh

κΈ°μ€€:

  • HTTP μ‹€νŒ¨μœ¨ 1% 미만
  • p95 500ms 미만
  • Check 성곡λ₯  99% 초과

Load Test

μ˜ˆμƒ λΆ€ν•˜μ—μ„œ μ„±λŠ₯ 기쀀을 λ§Œμ‘±ν•˜λŠ”μ§€ κ²€μ¦ν•©λ‹ˆλ‹€.

./scripts/run-load-test.sh

κΈ°μ€€:

  • HTTP μ‹€νŒ¨μœ¨ 1% 미만
  • p95 200ms 미만
  • p99 500ms 미만

Stress Test

λΆ€ν•˜ 증가에 따라 μ‹œμŠ€ν…œμ΄ μ–΄λŠ μ§€μ μ—μ„œ λΆˆμ•ˆμ •ν•΄μ§€λŠ”μ§€ κ΄€μ°°ν•©λ‹ˆλ‹€.

./scripts/run-stress-test.sh

Stress Testμ—μ„œλŠ” λ‹€μŒ λ³€ν™”λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • μ²˜λ¦¬λŸ‰ 증가 λ˜λŠ” 정체
  • p95 및 p99 급증
  • 5xx 였λ₯˜ λ°œμƒ
  • CPU μ‚¬μš©λ₯  μƒμŠΉ
  • JVM Heap 및 GC λ³€ν™”

λͺ¨λ‹ˆν„°λ§

Grafanaμ—μ„œ λ‹€μŒ 경둜둜 μ΄λ™ν•©λ‹ˆλ‹€.

Dashboards
β†’ System Design
β†’ Spring Boot Overview

κΈ°λ³Έ λŒ€μ‹œλ³΄λ“œμ—μ„œ λ‹€μŒ μ§€ν‘œλ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

  • Requests Per Second
  • p95 Response Time
  • p99 Response Time
  • 5xx Error Rate
  • JVM Heap Used
  • Process CPU Usage

Prometheus Target μƒνƒœ:

http://localhost:9090/targets

spring-boot Target이 UP이어야 ν•©λ‹ˆλ‹€.

μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 직접 μ‹€ν–‰

ν…ŒμŠ€νŠΈ

./gradlew clean test

μ‹€ν–‰

./gradlew bootRun

JAR λΉŒλ“œ

./gradlew clean bootJar

κ²°κ³Ό:

build/libs/app.jar

μ’…λ£Œ 및 정리

μ„œλΉ„μŠ€ μ’…λ£Œ

./scripts/stop.sh

Prometheus와 Grafana의 Named Volume은 μœ μ§€λ©λ‹ˆλ‹€.

μ»¨ν…Œμ΄λ„ˆμ™€ λΉŒλ“œ κ²°κ³Ό 정리

./scripts/clean.sh

μˆ˜μ§‘ λ°μ΄ν„°κΉŒμ§€ μ™„μ „νžˆ μ‚­μ œ

./scripts/clean.sh --volumes

--volumesλ₯Ό μ‚¬μš©ν•˜λ©΄ Prometheus와 Grafana의 μ €μž₯ 데이터가 μ‚­μ œλ©λ‹ˆλ‹€.

ν”„λ‘œμ νŠΈ μ§„ν–‰ 절차

각 μ‹œμŠ€ν…œ 섀계 ν”„λ‘œμ νŠΈλŠ” λ‹€μŒ μˆœμ„œλ‘œ μ§„ν–‰ν•©λ‹ˆλ‹€.

  1. 문제 및 μš”κ΅¬μ‚¬ν•­ μ •μ˜
  2. μš©λŸ‰ μ‚°μ •
  3. 초기 μ•„ν‚€ν…μ²˜ 섀계
  4. Baseline κ΅¬ν˜„
  5. λΆ€ν•˜ ν…ŒμŠ€νŠΈ
  6. 병λͺ© 뢄석
  7. ꡬ쑰 κ°œμ„ 
  8. λ™μΌν•œ 쑰건으둜 μž¬μΈ‘μ •
  9. κ²°κ³Ό 및 νŠΈλ ˆμ΄λ“œμ˜€ν”„ 정리
  10. 회고 μž‘μ„±

λ¬Έμ„œ

λ¬Έμ„œ λ‚΄μš©
Requirements κΈ°λŠ₯ 및 λΉ„κΈ°λŠ₯ μš”κ΅¬μ‚¬ν•­
Capacity Estimation νŠΈλž˜ν”½, μ €μž₯λŸ‰, λ„€νŠΈμ›Œν¬ μ‚°μ •
Architecture 전체 ꡬ쑰와 섀계 κ²°μ •
Experiment Baseline 및 κ°œμ„  μ‹€ν—˜
Retrospective κ²°κ³Ό, ν•œκ³„, 회고

ν…œν”Œλ¦Ώ μ‚¬μš© 방법

GitHub Repository ν™”λ©΄μ—μ„œ λ‹€μŒμ„ μ„ νƒν•©λ‹ˆλ‹€.

Use this template
β†’ Create a new repository

μƒˆ Repository 생성 ν›„:

cp .env.example .env
./scripts/start.sh
./scripts/run-smoke-test.sh

ν”„λ‘œμ νŠΈλ³„λ‘œ λ‹€μŒ ν•­λͺ©μ„ λ³€κ²½ν•©λ‹ˆλ‹€.

  • settings.gradle의 ν”„λ‘œμ νŠΈ 이름
  • spring.application.name
  • Java κΈ°λ³Έ νŒ¨ν‚€μ§€
  • Docker 이미지 이름
  • README ν”„λ‘œμ νŠΈ μ„€λͺ…
  • Prometheus와 Grafana의 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹λ³„μž
  • μš”κ΅¬μ‚¬ν•­ 및 섀계 λ¬Έμ„œ

ν˜„μž¬ λ²”μœ„

이 ν…œν”Œλ¦Ώμ—λŠ” νŠΉμ • ν”„λ‘œμ νŠΈμ— μ’…μ†λ˜λŠ” λ‹€μŒ κΈ°μˆ μ„ 기본으둜 ν¬ν•¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

  • Database
  • Redis
  • Kafka
  • Spring Security
  • JPA
  • QueryDSL

각 μ‹œμŠ€ν…œ 섀계 ν”„λ‘œμ νŠΈμ—μ„œ ν•„μš”ν•œ 기술만 μΆ”κ°€ν•©λ‹ˆλ‹€.

주의 사항

이 RepositoryλŠ” 둜컬 μ‹œμŠ€ν…œ 섀계 μ‹€ν—˜μ„ μœ„ν•œ ν…œν”Œλ¦Ώμž…λ‹ˆλ‹€.

ν˜„μž¬ ꡬ성은 λ‹€μŒ ν•­λͺ©μ„ 운영 ν™˜κ²½ μˆ˜μ€€μœΌλ‘œ μ œκ³΅ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

  • TLS
  • Secret Manager
  • λ°μ΄ν„°λ² μ΄μŠ€ 이쀑화
  • 닀쀑 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μΈμŠ€ν„΄μŠ€
  • 쀑앙 둜그 μˆ˜μ§‘
  • Alert Manager
  • λ°±μ—… 및 볡ꡬ

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages