복잡한뇌구조마냥

[Infra] Prometheus + Grafana 서버 모니터링 (Docker 기반) 본문

BE/Infra

[Infra] Prometheus + Grafana 서버 모니터링 (Docker 기반)

지금해냥 2025. 12. 3. 16:58

프로젝트가 커질수록 서버의 상태를 눈으로 확인할 수 있는 모니터링 환경은 필수가 된다.
프로젝트에서는 Prometheus + Grafana 조합으로 JVM, 트래픽, 메모리 사용량을 실시간 모니터링할 수 있는 환경을 구축했다.

Docker 기반이라 배포 환경에서도 그대로 사용 가능하고, 대시보드도 원하는 대로 커스터마이징할 수 있다.


1. Prometheus & Grafana란?

✔ Prometheus

  • 시계열(time-series) 기반 모니터링 + 데이터 수집 툴
  • 서버가 제공하는 /actuator/prometheus 엔드포인트를 일정 주기로 긁어오(scrape)며 메트릭 저장
  • JVM 메모리, CPU, 요청 수, HTTP 상태코드 등 다양한 지표 자동 수집

✔ Grafana

  • Prometheus에서 수집한 데이터를 기반으로 시각화 대시보드 제공
  • 막대/선/게이지/경고 알림 등 다양한 형태로 모니터링 구성 가능
  • 실제 서비스 운영 환경에서도 가장 널리 쓰이는 조합 (Kubernetes에서도 동일)

2. Docker 기반 Prometheus & Grafana 구성

프로젝트에서는 아래와 같이 docker-compose로 손쉽게 구성했다.

📌 docker-compose.yml (중요 부분만 발췌)

 
prometheus:
  image: prom/prometheus
  container_name: chwimeet-prometheus
  volumes:
    - ./prometheus.yml:/etc/prometheus/prometheus.yml
  ports:
    - "9090:9090"
  networks:
    - chwimeet-network
  restart: always

grafana:
  image: grafana/grafana
  container_name: chwimeet-grafana
  ports:
    - "3001:3000"
  environment:
    - GF_SECURITY_ADMIN_USER=admin
    - GF_SECURITY_ADMIN_PASSWORD=${SPRING__DATASOURCE__PASSWORD:-admin}
  volumes:
    - grafana-data:/var/lib/grafana
  networks:
    - chwimeet-network
  restart: always
  depends_on:
    - prometheus

3. 포트 3000 충돌 해결 (Grafana → 3001로 변경)

Grafana 기본 포트는 3000번이지만,
프로젝트에서 Frontend(Next.js)가 이미 3000번을 사용하고 있었기 때문에 충돌이 발생한다.

그래서 아래처럼 Grafana를 3001 포트로 노출했다.

 
ports:
  - "3001:3000"

=> 실제 접속 주소:

 
http://localhost:3001
http://<EC2_IP>:3001
https://grafana.chwimeet.store  (도메인 연결 시)

4. Prometheus 설정 파일(prometheus.yml)

Spring Boot Actuator에서 제공하는 메트릭을 긁어오도록 설정한다.

 
global:
  scrape_interval: 5s

scrape_configs:
  - job_name: 'spring-actuator'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['team1-app-001:8080']

✔ 주요 포인트

  • scrape_interval: 5s
    → 5초 간격으로 서버에서 메트릭 수집
  • metrics_path: /actuator/prometheus
    → Spring Boot Actuator가 Prometheus용 포맷으로 제공
  • targets
    → Docker 네트워크 내 컨테이너 이름으로 접근

5. Spring Boot 설정 (Actuator + Micrometer)

Prometheus는 Spring Boot Actuator가 제공하는 메트릭을 사용한다.
그래서 다음 의존성을 추가했다.

📦 build.gradle

 
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'

그리고 application.yml에서 Prometheus 엔드포인트를 활성화한다.

 
management:
  endpoints:
    web:
      exposure:
        include: health, prometheus

이제 /actuator/prometheus에서 수백 개의 JVM/HTTP 메트릭이 자동 제공된다.


6. Grafana에서 Prometheus 연결

1. Connections → Data sources → Add data source →Prometheus 선택

2. URL 입력 (docker로 올라가 있는 Prometheus 경로 입력)

3. Save & Test → 성공!


🎯 7. Grafana 대시보드 연결

예제) Spring Boot Statistics

  • 이미지대로 연결만 하면 쉽게 대시보드로 가시화 가능
  • 저는 이미 모니터링 중이라 에러가 보이는데, 처음 연결하시면 에러가 안보입니다.

대시보드 경로: https://grafana.com/grafana/dashboards/19004-spring-boot-statistics/

 

 

Spring Boot 3.x Statistics | Grafana Labs

Import the dashboard template Copy ID to clipboard or Download JSON

grafana.com

1) API 요청 시간 (Request duration per URI)

  • 각 API의 평균 응답 속도
  • p95 / p99 지연 시간 확인 가능
  • 특정 API가 갑자기 느려지는 시점을 빠르게 파악

예시 상황

  • AI 기능 호출이 순간적으로 느려지는 시간대
  • 이미지 업로드 API가 트래픽 증가로 느려질 때

2) 요청 수(Request count per URI)

  • 어떤 API가 가장 많이 호출되는지
  • 트래픽 패턴 파악
  • 병목 구간 예측 가능

예시 상황

  • 예약 기능/AI 검색 기능의 사용량을 시간대별로 분석
  • “어떤 API가 가장 많이 호출되는가?”를 근거 기반으로 판단

3) HTTP 상태 코드 분포

  • 4xx / 5xx 비율 확인
  • 배포 직후 오류 증가 감지
  • API 장애 탐지

예시 상황

  • 배포 직후 500 증가 → “새로 배포한 API 문제” 즉시 발견
  • 인증 문제로 401이 급격히 증가한 경우

4) Thread, connection pool, 에러 카운트

  • HikariCP 커넥션 부족 여부
  • 스레드 증가 탐지
  • 예외 발생 횟수 확인

8. 구축 후 실제 효과

프로젝트에서 모니터링을 적용한 후 다음과 같은 효과를 얻었다.

🔹 장애 파악 속도 단축

  • Memory leak 발생 여부를 즉시 파악
  • Thread 증가, DB connection pool 소진 등 운영 이슈를 빠르게 감지

🔹 성능 최적화 근거 확보

  • HTTP 요청 처리 시간 변화 추적
  • 특정 API 호출이 많은 시간대 분석
  • CPU/Heap 패턴 비교로 병목 지점 확인

🔹 배포 후 안정성 체크

  • 배포 직후 에러율 / 응답 시간 급증 여부 모니터링
  • 부하 테스트 결과 분석 가능

특히 AI 기능, 이미지 업로드, 웹소켓, 예약 시스템 등 다양한 기능이 동작하는 프로젝트라
모니터링이 훨씬 더 중요했다.


9. 마무리 정리

Prometheus는 데이터를 수집하고, Grafana는 그 데이터를 시각화한다.

LIST