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 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
.
βββ 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
μ ν리μΌμ΄μ μ€ν μ¬λΆμ κΈ°λ³Έ 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"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 κ³μ μ λ‘컬 μ€νμ©μ λλ€. μΈλΆ νκ²½μμλ λ°λμ λ³κ²½ν΄μΌ ν©λλ€.
./scripts/start.shμ§μ μ€ννλ €λ©΄:
docker compose up --build -ddocker compose psSpring Boot 컨ν μ΄λκ° λ€μ μνμ¬μΌ ν©λλ€.
healthy
| μλΉμ€ | μ£Όμ |
|---|---|
| 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λ μμ μ€ννμ§ μκ³ ν μ€νΈ μ μΌνμ± μ»¨ν μ΄λλ‘ μ€νλ©λλ€.
APIκ° κΈ°λ³Έμ μΌλ‘ μ μ λμνλμ§ κ²μ¦ν©λλ€.
./scripts/run-smoke-test.shκΈ°μ€:
- HTTP μ€ν¨μ¨ 1% λ―Έλ§
- p95 500ms λ―Έλ§
- Check μ±κ³΅λ₯ 99% μ΄κ³Ό
μμ λΆνμμ μ±λ₯ κΈ°μ€μ λ§μ‘±νλμ§ κ²μ¦ν©λλ€.
./scripts/run-load-test.shκΈ°μ€:
- HTTP μ€ν¨μ¨ 1% λ―Έλ§
- p95 200ms λ―Έλ§
- p99 500ms λ―Έλ§
λΆν μ¦κ°μ λ°λΌ μμ€ν μ΄ μ΄λ μ§μ μμ λΆμμ ν΄μ§λμ§ κ΄μ°°ν©λλ€.
./scripts/run-stress-test.shStress 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./gradlew clean bootJarκ²°κ³Ό:
build/libs/app.jar
./scripts/stop.shPrometheusμ Grafanaμ Named Volumeμ μ μ§λ©λλ€.
./scripts/clean.sh./scripts/clean.sh --volumes--volumesλ₯Ό μ¬μ©νλ©΄ Prometheusμ Grafanaμ μ μ₯ λ°μ΄ν°κ° μμ λ©λλ€.
κ° μμ€ν μ€κ³ νλ‘μ νΈλ λ€μ μμλ‘ μ§νν©λλ€.
- λ¬Έμ λ° μꡬμ¬ν μ μ
- μ©λ μ°μ
- μ΄κΈ° μν€ν μ² μ€κ³
- Baseline ꡬν
- λΆν ν μ€νΈ
- λ³λͺ© λΆμ
- ꡬ쑰 κ°μ
- λμΌν 쑰건μΌλ‘ μ¬μΈ‘μ
- κ²°κ³Ό λ° νΈλ μ΄λμ€ν μ 리
- νκ³ μμ±
| λ¬Έμ | λ΄μ© |
|---|---|
| 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
- λ°±μ λ° λ³΅κ΅¬