-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
📌 Spring Boot Actuator + Micrometer에서 Prometheus와 Grafana로 시각화할 때 실무에서 자주 쓰이는 PromQL 쿼리
1. HTTP 요청 수
sum(rate(http_server_requests_seconds_count[1m])) by (method, status)
- 최근 1분간의 요청 수를 초당 비율로 집계
- method, status 별 분류 가능 (GET, POST, 200, 500 등)
- 트래픽 모니터링, API 사용량 파악에 유용
2. HTTP 요청 평균 응답 시간
sum(rate(http_server_requests_seconds_sum[1m])) by (uri)
/
sum(rate(http_server_requests_seconds_count[1m])) by (uri)
- 요청별 평균 응답 시간 (초)
- uri 경로별로 집계 가능
- 특정 API가 느린지 확인할 때 사용
3. JVM Heap 메모리 사용량
jvm_memory_used_bytes{area="heap"}
/
jvm_memory_max_bytes{area="heap"}
- JVM 힙 사용률 (0.0 ~ 1.0 사이)
- 메모리 누수나 과도한 GC를 감지할 수 있음
4. 활성 스레드 수 (JVM Thread)
jvm_threads_live_threads
- 현재 활성화된 JVM 스레드 개수
- 스레드 누수나 고부하 감지에 사용
5. 애플리케이션 가용성 (UP 여부)
up{job="spring-app"}
- Prometheus에서 수집 가능한지 여부
- 0이면 애플리케이션이 죽었거나 scrape 실패한 것
📌 Grafana 시각화용 추천 PromQL
| 카테고리 | PromQL | 설명 | 추천 차트 |
|---|---|---|---|
| ① HTTP 요청 수 | sum(rate(http_server_requests_seconds_count[1m])) by (uri) | URI별 초당 요청 수 | Bar chart, Time series (Lines) |
| ② HTTP 응답 시간 | sum(rate(http_server_requests_seconds_sum[1m])) by (uri) / sum(rate(http_server_requests_seconds_count[1m])) by (uri) | URI별 평균 응답 시간 (초) | Time series, Heatmap |
| ③ JVM 힙 메모리 사용률 | jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} | 힙 사용률 (0.0~1.0) | Gauge, Time series |
| ④ CPU 사용률 (시스템 전체) | 100 - (avg by (instance)(irate(node_cpu_seconds_total{mode="idle"}[1m])) * 100) | 노드 전체 CPU 사용률 (%) | Time series, Stat panel |
| ⑤ 애플리케이션 상태 | up{job="spring-app"} | 1: 정상, 0: 다운 | Single stat, Table, Status panel |
📌 Spring Boot + Prometheus + Alertmanager + Slack 연동 + 부하 테스트 자동화 예제
1. Prometheus 설정 (prometheus.yml)
global:
scrape_interval: 5s
rule_files:
- "alert.rules.yml"
scrape_configs:
- job_name: 'spring-local'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8080']
# - targets: ['app:8080']
alerting:
alertmanagers:
- static_configs:
- targets: ['host.docker.internal:9093']- 5초마다 /actuator/prometheus에서 메트릭 수집
- alert.rules.yml에 정의된 조건 충족 시 AlertManager(9093)로 알림 발송
2. 알림 조건 정의 (alert.rules.yml)
groups:
- name: example
rules:
- alert: HighRequestRate
expr: rate(http_server_requests_seconds_count[10s]) > 10
for: 10s
labels:
severity: warning
annotations:
summary: "Request rate high"- 최근 10초 동안 요청 수가 초당 10건을 초과하면 HighRequestRate 알림 발생
- 10초간 조건이 유지돼야 알림 전송
- summary는 Slack에 전달되는 메시지 내용
3. AlertManager 설정 (alertmanager.yml)
route:
receiver: 'slack-notifications'
receivers:
- name: 'slack-notifications'
slack_configs:
- text: "{{ .CommonAnnotations.summary }}"
# text: "일어나라!"
api_url: 'https://hooks.slack.com/services/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'
channel: 'alert'
send_resolved: true- slack-notifications 수신기로 알림 전송
- Slack Webhook API를 통해 #alert 채널로 전송
- 알림 해제(resolved) 시에도 메시지 전송
4. 부하 테스트 스크립트 (test.sh)
#!/bin/bash
# --- 설정 ---
URL="http://localhost:8080/200" # 테스트할 URL을 입력하세요.
TOTAL_REQUESTS=100000 # 보낼 총 요청 수를 입력하세요.
CONCURRENT_USERS=5 # 동시에 실행할 사용자(프로세스) 수를 입력하세요.
OUTPUT_FILE="load_test_results.log" # 결과(HTTP 상태 코드)를 저장할 파일 이름
# ------------
# 변수 초기화
success_count=0
fail_count=0
request_count=0
pids=() # 백그라운드 프로세스 ID 저장 배열
# 이전 로그 파일 삭제 (선택 사항)
> "$OUTPUT_FILE"
echo "🚀 부하 테스트 시작..."
echo "-----------------------------------"
echo "대상 URL: $URL"
echo "총 요청 수: $TOTAL_REQUESTS"
echo "동시 사용자 수: $CONCURRENT_USERS"
echo "-----------------------------------"
start_time=$(date +%s)
# 요청을 보내는 함수
function send_request {
local url=$1
# curl: -s (silent), -o /dev/null (출력 버리기), -w "%{http_code}" (HTTP 상태 코드만 출력)
http_code=$(curl -s -o /dev/null -w "%{http_code}" "$url")
echo "$http_code" >> "$OUTPUT_FILE" # 파일에 상태 코드 기록
}
# 총 요청 수에 도달할 때까지 반복
while [ $request_count -lt $TOTAL_REQUESTS ]; do
# 현재 실행 중인 백그라운드 작업 수 확인
current_jobs=$(jobs -p | wc -l)
# 설정된 동시 사용자 수보다 적게 실행 중이고, 총 요청 수에 도달하지 않았다면
while [ $current_jobs -lt $CONCURRENT_USERS ] && [ $request_count -lt $TOTAL_REQUESTS ]; do
send_request "$URL" & # 함수를 백그라운드로 실행
pids+=($!) # 백그라운드 프로세스 ID 저장
request_count=$((request_count + 1))
current_jobs=$(jobs -p | wc -l)
# 진행 상황 표시 ( \r 을 사용하여 같은 줄에 덮어씀)
echo -ne "요청 보냄: $request_count / $TOTAL_REQUESTS | 현재 동시 요청: $current_jobs \r"
done
# 동시 사용자 수에 도달했다면, 백그라운드 작업 중 하나가 끝날 때까지 기다림
# -n 옵션: 실행 중인 작업 중 아무거나 하나가 종료되면 즉시 반환
if [ $current_jobs -ge $CONCURRENT_USERS ]; then
wait -n
fi
# 종료된 프로세스 ID 목록에서 제거 (선택 사항, 더 정확한 관리를 위해)
# 실제로는 wait -n이 하나씩 처리하므로 이 부분은 단순화 가능
done
# 남아있는 모든 백그라운드 작업이 끝날 때까지 기다림
wait
echo -e "\n-----------------------------------" # 줄바꿈 후 구분선
end_time=$(date +%s)
duration=$((end_time - start_time))
echo "⏳ 모든 요청 완료. 결과 집계 중..."
# 결과 파일 분석
while read -r code; do
if [[ $code -ge 200 && $code -lt 400 ]]; then
success_count=$((success_count + 1))
else
fail_count=$((fail_count + 1))
fi
done < "$OUTPUT_FILE"
echo "✅ 부하 테스트 종료."
echo "-----------------------------------"
echo "총 요청 수: $TOTAL_REQUESTS"
echo "성공 요청: $success_count"
echo "실패 요청: $fail_count"
echo "총 소요 시간: $duration 초"
if [ $duration -gt 0 ]; then
# bc 계산기를 사용하여 초당 요청 수(RPS) 계산 (소수점 둘째 자리까지)
rps=$(echo "scale=2; $TOTAL_REQUESTS / $duration" | bc)
echo "초당 요청 수 (RPS): $rps"
else
echo "소요 시간이 너무 짧아 RPS를 계산할 수 없습니다."
fi
echo "-----------------------------------"
echo "상세 결과(HTTP 상태 코드)는 $OUTPUT_FILE 파일을 확인하세요."- 10만 건의 HTTP 요청을 5개의 프로세스로 병렬 전송
- 응답 코드별로 성공/실패 카운팅
- 실행 시간 측정 및 초당 요청 수(RPS) 계산
- Slack 알림 트리거 실습용으로 매우 유용
5. 컨테이너 실행 명령어
# Prometheus 컨테이너 실행
docker run -d \
-p 9090:9090 \
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
-v $(pwd)/alert.rules.yml:/etc/prometheus/alert.rules.yml \
--name prometheus \
prom/prometheus:latest
# Alertmanager 컨테이너 실행
docker run -d \
-p 9093:9093 \
-v $(pwd)/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
--name alertmanager \
prom/alertmanager:latest
# 부하 테스트 실행
sh test.sh
# docker rm -f prometheus
# docker restart prometheus
# localhost:9090
# docker rm -f alertmanager
# docker restart alertmanager
# localhost:90936. 실습 결과 스크린샷
📌 Grafana 실습 – Prometheus 기반 모니터링 대시보드 구축
1. Grafana 컨테이너 실행
docker run -d -p 3000:3000 grafana/grafana- 실행 후 웹 브라우저에서 접속: http://localhost:3000/login
- 초기 로그인 정보:
- ID: admin
- PW: admin (로그인 후 반드시 비밀번호 변경)
2. Prometheus 데이터 소스 연결
-
경로
- 왼쪽 사이드바 하단 → Connections 클릭 → Data sources → Add data source 선택
-
Prometheus 설정
- Prometheus 선택 후, 아래처럼 설정
| 항목 | 값 |
|---|---|
| URL | http://host.docker.internal:9090 |
| Access | Server (default) |
| Save & Test | 클릭하여 연결 테스트 |
- http://localhost:9090은 Docker 내부에서는 접근 불가 → host.docker.internal 사용해야 함
3. 대시보드 생성 및 시각화
- 대시보드 생성
- 상단 메뉴에서 Dashboard 클릭 → + New → Add visualization
- 데이터 소스 선택
- Prometheus 선택
- 예시 메트릭
- 메트릭 입력창에 PromQL을 입력 (예: HTTP 요청 수)
rate(http_server_requests_seconds_count[1m])
