키워드 : 클라이언트/서버 관점, Grafana, Prometheus, Spring Actuator, Node Exporter, k6
[8]편에서 CloudAttend 애플리케이션이 홈서버에서 정상 동작하는 걸 확인했다.
이제 한 가지 질문이 생겼다.
"이 서버가 얼마나 버틸 수 있을까?"
답을 내려면 먼저 "측정할 수 있는 환경"을 만들어야 한다.
아래 아키텍처가 이번 편에서 완성할 그림이다.

(1) HTTP 트래픽 흐름 : k6가 쏜 HTTP 요청이 공유기-> nginx -> backend로 흘러들어감.
(2) 메트릭 수집 흐름 : Prometheus가 15초마다 backend(Spring Actuator)와 Node Exporter를 긁어가고,
Grafana가 시각화함
-> 즉 클라이언트 관점(k6)과 서버 관점(Grafana)를 동시에 들여다보는 구조
🚀 모니터링 스택을 구성하고 테스트로 검증까지 !
(1) 모니터링 스택 구성 이거!!
- Prometheus + Grafana + Node Exporter를 Docker Compose에 추가
- 서버의 CPU 및 메모리 사용량(서버 관점)을 실시간으로 모니터링
(2) k6 부하테스트 (← 이건 다음편에서)
- MacBook에서 k6로 실제 HTTP 요청을 홈서버에 쏘고,
응답시간 및 에러율(클라이언트 관점)을 측정
🔹 Step 1. docker-compose.yml에 3개 서비스 추가
- docker-compose.yml에 3개 서비스 추가
- 기존 서비스(mysql, backend, frontend, nginx)에 아래 3개를 추가한다.
# Prometheus - 메트릭을 수집하고 저장
prometheus:
image: prom/prometheus
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
networks:
- app-network
# Grafana - 수집한 데이터를 시각화
grafana:
image: grafana/grafana
volumes:
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
depends_on:
- prometheus
networks:
- app-network
# Node Exporter - 홈서버 PC의 OS 메트릭을 수집
node-exporter:
image: prom/node-exporter
networks:
- app-network
volumes 섹션에도 추가한다.
volumes:
mysql_data:
prometheus_data: # ← 추가
grafana_data: # ← 추가
💡 networks와 volumes
(1) networks
- Docker는 기본적으로 컨테이너끼리 서로 찾지 못한다.
- app-network라는 가상 내부망을 만들고 같은 네트워크로 묶어줘야 서로 이름으로 접근할 수 있다.
(DB_HOST: mysql처럼 IP가 아닌 컨테이너 이름으로 접근할 수 있는 이유)
(2) volumes
- 컨테이너가 꺼지면 내부 데이터는 전부 사라짐.
이때 named volume에 저장해두면 재시작해도 데이터가 유지됨.
🔹 Step 2. prometheus.yml 작성
프로젝트 루트에 prometheus 디렉토리를 만들고 설정 파일을 작성한다.
# prometheus/prometheus.yml
global:
scrape_interval: 15s # 모든 job 기본값: 15초마다 수집
scrape_configs:
- job_name: 'backend'
metrics_path: '/actuator/prometheus' # Spring Actuator 엔드포인트
static_configs:
- targets: ['backend:8080']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
💡 Prometheus는 Pull 방식 !
- 각 대상이 Prometheus에게 데이터를 보내는 게 아니라,
- Prometheus가 15초마다 직접 찾아가서 데이터를 가져온다.
15초마다:
(1) Prometheus → GET backend:8080/actuator/prometheus
: JVM/HTTP 메트릭 수집(HTTP 요청 수, 응답시간, DB 커넥션 풀 등)
(2) Prometheus → GET node-exporter:9100/metrics → OS 메트릭 수집
: OS 자원 사용량 (CPU, RAM, 디스크 I/O 등)
💡 의존성을 두 개 추가해주자
implementation 'io.micrometer:micrometer-registry-prometheus' // 측정
implementation 'org.springframework.boot:spring-boot-starter-actuator' // 노출
💡 Spring Actuator? → 어댑터 !
- Spring Boot 앱 내부 데이터는 Prometheus가 읽을 수 없는 형태다.
- 읽을 수 있는 포맷으로 바꾸는 역할을 수행한다.
JVM 내부 데이터
↓
Micrometer (측정 도구)
↓
Actuator /actuator/prometheus (Prometheus 포맷으로 변환 후 노출)
↓
Prometheus가 15초마다 읽어감
// Actuator가 데이터를 push하는게 아님.
// 그냥 창구를 열어두고 Prometheus가 읽어가길 기다릴 뿐
🔹 Step 3. docker compose up --build
docker compose up --build -d
컨테이너 7개 다 잘 뜨는거 확인 !
✔ Image prom/prometheus Pulled
✔ Image grafana/grafana Pulled
✔ Image prom/node-exporter Pulled
✔ Volume prometheus_data Created
✔ Volume grafana_data Created
✔ Container prometheus-1 Started
✔ Container grafana-1 Started
✔ Container node-exporter-1 Started
✔ Container backend-1 Started
✔ Container frontend-1 Healthy
✔ Container nginx-1 Running
🔹 Step 4. Grafana 설정
먼저 접속해주고, Prometheus 데이터소스를 연결해준다
✅ "잘 동작하나?" - stress로 CPU 튀는지 확인
모니터링 환경 세팅은 끝났다.
이제 대시보드가 실제로 잘 동작하는지 확인하기 위해 stress 툴을 사용해서 부하를 줘보자.
stress --cpu 16 --timeout 30
# 홈서버 pc는 16코어, 30초 동안 부하
Grafana에서 CPU 그래프가 바로 튀는 것을 확인 !
모니터링 스택이 잘 동작한다.


다음 편 예고
모니터링 환경이 갖춰졌으니, 이제 실제로 때려볼 차례 !
다음 편에서는 클라이언트인 MacBook에서 k6로 실제 트래픽을 홈서버에 쏘고,
k6 결과와 Grafana 메트릭을 같이 분석하려한다.
얼마나 버티는지, 어디서 무너지는지 데이터로 확인할 예정이다.