✅ Prometheus란?
애플리케이션 및 시스템에서 다양한 메트릭을 시계열 데이터로 수집하고 저장하는 일종의 데이터베이스를 말한다. Prometheus는 다음의 특징을 가진다.
- 시계열 데이터 모델로, 각 시계열 데이터는 메트릭의 이름과 키/값 쌍으로 식별됨
- PromQL이라는 쿼리 언어를 통해 수집된 메트릭 데이터를 필터링하고 분석할 수 있다.
- 분산 스토리지에 의존하지 않으며, 단일 서버 노드가 자율적으로 작동한다.
- HTTP를 통해 Pull 방식으로 데이터를 수집한다. 즉, 내 어플리케이션의 특정 api 엔드포인트를 통해 데이터를 요청해 받아오는 방식이다.
- Pull 방식을 기본적으로 사용하지만 단기적인 작업이나 백그라운드 작업 등 Pull이 어려운 경우를 위해 Pushgateway를 통해 Push 모델도 지원한다.
- Kubernetes, Consul, EC2와 같은 환경과의 통합을 통해, 새로운 인스턴스가 추가되거나 제거될 때 이를 자동으로 감지하고 업데이트할 수 있다. 정적 설정을 통해 수동으로 타겟을 지정하는 것도 가능하다.
- 자체적으로 웹 UI를 통해 그래프 기능을 제공하며 그라파나와의 연동을 통해 더욱 다양한 시각화가 가능하다.
✅ Prometheus 도입 이유
지금까지 PLG 스택(Promtail + Loki + Grafana)을 통해 HTTP 요청과 응답에 대한 로그를 모니터링 해서 대시보드로 구성했었다.
대시보드를 통해 표현한 정보는 다음과 같다.
- HTTP Method 분포도
- API 분포도
- IP 분포도
- 오류, 에러 로그
- API당 오류 발생횟수
- API별 평균 실행 횟수
😭 로그를 통한 모니터링의 한계
- 로그를 통해 HTTP 요청/응답에 대한 자세한 정보를 확인할 수는 있었지만 시간흐름에 대한 요청의 변화를 분석하기는 어렵다
- 로그로 남겨진 HTTP 요청/응답 데이터만 분석이 가능하다는 단점이 있다. 물론 로그를 다양하게 추가해서 모니터링을 구축할 수 있겠지만 그러면 로그 데이터가 너무 방대해진다.
💡 Prometheus의 도입
Prometheus를 활용하면 앞서 말한 한계들을 모두 극복할 수 있다.
- Prometheus는 시스템의 데이터를 연속적인 시계열 데이터로 기록하는데 특화되어 있다. 그렇기 때문에 시간 흐름에 따른 변화를 분석하기 용이하다.
- 또한 시스템에서 다양한 종류의 데이터를 수집하기 때문에 분석의 폭이 넓어진다는 장점도 있다. HTTP 요청/응답은 물론 CPU 사용량, 메모리 사용량, 데이터베이스 커넥션 풀 사용량 등 다양한 데이터를 기본적으로 분석한다. 이뿐만 아니라 가입 회원 수, 주문량 등 비즈니스의 특화된 정보 또한 별도의 설정을 통해 분석할 수 있다.
✅ Prometheus 아키텍처
Prometheus의 전반적인 아키텍처는 다음과 같다.
스프링부트 프로젝트가 Prometheus targets에 해당된다고 생각하면 된다.
Prometheus targets으로 부터 다양한 메트릭을 수집해서 Prometheus Server에 저장하고 해당 데이터를 Grafana를 통해 시각화하거나 Alertmanager를 통해 특정 상황에 따라 알람을 보낼 수 있다.
하지만 나는 Promtheus 환경을 별도로 구축하는 것이 아니라 Grafana Cloud에서 제공하는 환경에서 Prometheus를 사용할 것이기 때문에 하나의 추가적인 과정이 필요하다.
바로 Grafana Agent를 사용해야 한다.
Grafana Cloud 환경의 Prometheus에서는 Pull 방식의 메트릭 수집을 지원하지 않는다고 한다. 따라서 별도로 직접 Prometheus에 Push를 해줘야 하는데 그 역할을 하는 것이 Grafana Agent이다.
✅ Spring Actuator와 Micrometer
Spring Actuator란?
💡스프링 부트 애플리케이션에 다양한 관리 기능을 추가해주는 모듈로, 애플리케이션의 상태, 성능, 메트릭, 환경 변수, 로깅 설정 등을 손쉽게 모니터링하고 관리할 수 있도록 해준다.
Spring Actuator는 다양한 내장 엔드포인트를 제공하여, 애플리케이션 상태를 API를 통해 확인할 수 있다.
Micrometer란?
💡애플리케이션의 메트릭 수집을 표준화하는 라이브러리로, Actuator와 연동하여 CPU 사용량, 메모리 사용량, HTTP 요청 시간 등 다양한 메트릭을 수집하고, 이를 Prometheus, InfluxDB, Graphite 등 다양한 모니터링 시스템으로 내보낼 수 있다.
✅ 설치하기
1️⃣ Spring Actuator & Prometheus 의존성 추가
// Spring Actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// Prometheus
implementation 'io.micrometer:micrometer-registry-prometheus'
Micrometer는 Spring Actuator를 추가하면 기본적으로 함께 설치되며, Prometheus는 별도로 추가해야한다.
2️⃣ application.yml
spring actuator에 관한 설정부분이다.
spring actuator가 모니터링한 수 많은 데이터 중 외부에 노출시킬 엔드포인트를 적는 곳이다.
actuator가 제공하는 엔드포인트들은 외부에 노출되면 안되는 민감한 정보들이 들어있기 때문에 최소한의 경로만 허용해야한다.
management:
endpoints:
web:
exposure:
include: prometheus
prometheus:
metrics:
export:
enabled: true
- web.exposure.include: prometheus
prometheus를 사용하기 위해서 노출되어야 하는 엔드포인트이다.
3️⃣ Grafana Agent
actuator/prometheus 엔드포인트에서 모니터링 정보를 수집해서 prometheus로 보내는 역할을 한다.
Docker Image를 통해 설치하였다.
services:
grafana-agent:
image: grafana/agent:latest
container_name: grafana-agent
volumes:
- /home/ubuntu/prometheus:/etc/grafana-agent
command:
- -config.file=/etc/grafana-agent/config.yml
- -config.expand-env=true
environment:
- PROMETHEUS_USERNAME
- PROMETHEUS_PASSWORD
4️⃣ Grafana Agent config 파일
Grafana Agent가 해야 할 일을 적는 부분이라고 생각하면 된다.
metrics:
configs:
- name: spring-boot-app
scrape_configs:
- job_name: 'spring-boot'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['xxxx:xx'] # 스프링 부트 애플리케이션의 호스트와 포트
remote_write:
- url: "<https://prometheus-prod-49-prod-ap-northeast-0.grafana.net/api/prom/push>"
basic_auth:
username: ${PROMETHEUS_USERNAME}
password: ${PROMETHEUS_PASSWORD}
targets(스프링부트)의 /actuator/prometheus에 접근해 모니터링 정보를 얻고 그 정보를 prometheus에 전송한다.
5️⃣ /actuator 엔드포인트 보안설정
/actuator에는 노출되서는 안되는 정보들이 많다. 따라서 외부에서 함부로 접근이 불가능하게 해야 한다.
그렇게 하기 위해 EC2에 설치되어 있는 Nginx서버에서 설정을 해주었다.
# /actuator 경로에 대해 특정 IP만 허용
location /actuator {
allow x.x.x.x; # Grafana Agent가 실행 중인 IP
deny all; # 그 외 IP는 접근 차단
}
/actuator 경로로 오는 요청은 Grafana Agent로 부터 오는 요청만 받겠다는 의미이다.
✅ Grafana 대시보드
대시보드의 기본틀은 다음의 대시보드를 활용했다.
1️⃣ 기본분석
⬇️ 분석항목들
- Uptime: 어플리케이션 가동 지속 시간
- Start time: 어플리케이션 가동 시작 시간
- Heap Used: JVM Heap 메모리 사용률
- Non-Heap Used: JVM Non-Heap 메모리 사용률
- Process Open Files: 프로세스가 열고 있는 파일의 수, 프로세스가 열수 있는 최대 파일의 수
- CPU Usage: 시스템 전체 CPU 사용량, 어플리케이션 CPU 사용량
- Load Average: 1분간 평균 부하(CPU 코어 사용 수)
- JVM Heap/Non-Heap 메모리 사용량(바이트 수)
- Threads: 전체 스레드 수(데몬 스레드 수)
- Memory Allocate/Promote: 메모리 할당/승격 속도 변화율
- Classes Loaded: 로드된 클래스 수
- Classes Unloaded: 최근 5분 동안 JVM에서 언로드된 클래스 수의 변동 속도
- Direct Buffers: Direct Buffer 사용량
- Mapped Buffers: Mapped Buffer 사용량
- GC Count: JVM이 초당 몇 번의 GC 일시정지를 겪고 있는지를 나타내는 값
- GC Stop the world Duration: JVM이 초당 얼마나 많은 시간을 GC 일시정지에 사용하고 있는지를 나타내는 값
- Connections Size: 커넥션 풀의 최댓값
- Connection Timeout Count: 커넥션 타임아웃의 수
- Connections: 사용 중인 커넥션의 수, 놀고 있는 커넥션의 수, 대기 중인 커넥션 요청 수
- Connection Creation Time: 커넥션 생성 시간
- Connection Usage Time: 커넥션 사용 시간
- Connection Acquire Time: 커넥션 습득 시간
2️⃣ HTTP 모니터링
- 이전에 PLG스택을 통해 구축한 대시보드에 몇가지를 추가했다.
- 초당 요청수
- API별 초당 요청 수
- API별 평균 실행시간
✅ 알람 설정하기
Grafana의 Alert기능을 사용해 메모리 사용률, CPU 사용률이 일정 임계치를 넘어가면 이메일이 오도록 설정하였다.
1️⃣ 메모리 사용률
2️⃣ CPU 사용률
✅ 참고자료
스프링 부트 - 핵심 원리와 활용 강의 | 김영한 - 인프런
Prometheus와 Grafana로 하는 모니터링 구축
Security Actuator 안전하게 사용하기 | 우아한형제들 기술블로그
'데브코스 > 실습 & 프로젝트' 카테고리의 다른 글
[최종 프로젝트] 질문 생성 기능 - 1. 질문 생성을 위한 생성형 AI 모델 조사 (2) | 2024.12.28 |
---|---|
[최종 프로젝트] Jira 도입기 ( + 회고) (2) | 2024.12.27 |
[2-3차 프로젝트] PLG 스택 운영환경에 배포 하기 (1) | 2024.11.05 |
[2-3차 프로젝트] Grafana 알림 기능 사용하기 (0) | 2024.11.05 |
[2-3차 프로젝트] Grafana Loki: logfmt와 Promtail 라벨링 성능 비교 (0) | 2024.11.03 |