olrlobt
[Spring] Monitoring 도구 Prometheus란? 본문
Prometheus란?
Prometheus는 애플리케이션의 성능 모니터링과 경고 알림을 위해 널리 사용되는 오픈소스 시스템으로, 특히 시계열 데이터(Time Series Data) 수집과 분석에 특화된 툴이다. 시계열 데이터는 특정 시간에 기록된 메트릭 값을 기반으로 시간의 흐름에 따라 변화하는 데이터를 추적하고 저장하는 방식이다. 이러한 방식은 시스템 성능을 모니터링하고, 문제 발생 시 그 원인을 파악하는 데 유용하다.
Prometheus는 특히 클라우드 네이티브 환경과 분산 시스템에서 널리 사용되며, 안정적이고 확장 가능한 모니터링 솔루션을 제공한다. 다양한 플랫폼에서 손쉽게 통합할 수 있으며, 애플리케이션의 리소스 사용률, 요청 처리 시간, 데이터베이스 성능 등 중요한 메트릭을 실시간으로 수집하고 분석할 수 있다.
Prometheus의 알림(Alerting) 기능은, 지정된 조건에 맞춰 알림을 설정하여 CPU 사용률이 일정 수치를 초과하거나 메모리 사용량이 급증하는 상황을 즉시 파악하고 대응할 수 있다. 이러한 알림은 이메일, Slack 등 다양한 채널을 통해 전달되며, 운영자의 빠른 대응을 도와준다.
결론적으로, Prometheus는 현대 IT 시스템의 실시간 모니터링과 경보 시스템 구축에 매우 적합한 도구로, 특히 대규모의 분산된 클라우드 환경에서 안정성을 유지하고 성능을 최적화하는 데 중요한 역할을 한다.
Prometheus는 Grafana와 같은 시각화 도구와도 쉽게 통합되어, 직관적인 대시보드로 실시간 모니터링을 가능하게 한다. 하지만 나는 모니터링 도구의 사용이 처음이기 때문에, Grafana의 도입은 다음 포스팅에서 다루고 이번 포스팅에서는 Prometheus에만 집중하려 한다.
Spring Actuator
Spring Actuator는 Spring Boot 애플리케이션의 모니터링 및 관리 기능을 제공하는 라이브러리로, 개발자가 애플리케이션의 상태와 운영 정보를 쉽게 확인하고 관리할 수 있도록 도와준다. 특히, 애플리케이션의 상태와 성능 관련 데이터를 자동으로 수집하고 노출함으로써, 별도의 코드 작성 없이도 JVM 메모리 사용량, CPU 사용률, 쓰레드 상태, 데이터베이스 커넥션 상태 등을 손쉽게 모니터링할 수 있다.
Actuator는 Prometheus와 같은 모니터링 도구가 필요한 메트릭을 '/actuator/prometheus' 엔드포인트에서 제공하여, 애플리케이션 내부에서 메트릭을 직접 관리할 필요 없이 Prometheus가 이를 수집해 갈 수 있도록 한다. 또한, Actuator는 여러 가지 기본적인 성능 메트릭을 내장하고 있어, 이를 Prometheus에서 바로 활용할 수 있다.
이처럼 Actuator는 Spring 애플리케이션과 Prometheus 간의 통합을 간단하게 처리하여, 시스템 성능 모니터링과 운영 관리의 복잡성을 크게 줄여준다.
Spring Actuator 설정
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '3.2.5'
Build.gradle에 Spring Actuator의 의존성을 추가해 주었다.
Spring Actuator는 다양한 관리 및 모니터링 기능을 제공하며, 이를 위해 여러 엔드포인트를 제공한다.
하지만 Actuator 엔드포인트를 기본적으로 노출하면 애플리케이션에 보안상의 위험이 발생할 수 있고, 불필요한 엔드포인트가 노출될 경우 애플리케이션의 성능에 영향을 미칠 수 있다.
따라서, application.properties 또는 application.yml 파일에서 설정을 통해 필요하지 않은 엔드포인트에 대한 접근을 제한하자. 이번 포스팅에서는 prometheus만 필요하기 때문에 , health를 제외한 나머지 불필요한 엔드포인트는 접근을 차단하도록 설정했다.
management:
endpoints:
web:
exposure:
include: prometheus, health # prometheus와 health 엔드포인트 활성화
prometheus:
metrics:
export:
enabled: true # Prometheus 메트릭 활성화
endpoint:
prometheus:
enabled: true # Prometheus 엔드포인트 활성화
health:
enabled: true # Health 엔드포인트 활성화
이제 설정을 마쳤다면, Spring Actuator를 통해 메트릭 정보를 얻어올 수 있다.
localhost:8080/actuator/prometheus로 GET 요청을 보내면, Prometheus에서 사용하는 형식으로 메트릭 값이 변환되어 반환된다.
이 형식은 메트릭 이름, 라벨, 그리고 값으로 구성되어 있다.
즉, Prometheus는 이 엔드포인트를 통해 주기적으로 스크래핑하여 메트릭 데이터를 수집한다. Prometheus 서버는 이 데이터를 가져와 내부적으로 시계열 데이터로 저장하는데, 시계열 데이터는 특정 시점에 기록된 수치나 상태 값을 나타내며, 주로 숫자형 값으로 구성된다.
위 정보에서 메트릭 이름, 라벨, 그리고 타임스탬프를 조합하여 고유한 시계열 데이터를 생성하고, 이를 통해 시간에 따라 변화하는 시스템 상태를 추적하는 것이다.
Prometheus 설치
Prometheus 설정
Build.gradle 또는 pom.xml에 Prometheus 관련 의존성을 추가해 주자.
implementation 'io.micrometer:micrometer-registry-prometheus'
Spring Boot 애플리케이션에서 메트릭을 제공하고, Prometheus가 이를 수집할 수 있도록 하려면 Prometheus 서버를 설정해야 한다.
다음과 같이 prometheus.yml을 작성한다.
global:
scrape_interval: 15s # 기본적으로 15초마다 메트릭을 수집
# evaluation_interval: 15s # 15초마다 알림 규칙을 평가
scrape_configs:
- job_name: 'spring-actuator'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['spring-blue:8080', 'spring-green:8080'] # Spring Boot 애플리케이션이 실행 중인 호스트와 포트
Prometheus 서버의 설정 파일인 prometheus.yml에서 Spring Boot 애플리케이션의 /actuator/prometheus 엔드포인트를 15초마다 스크래핑하도록 설정했다. 실제로 사용해 보니, 생각보다 텀이 길게 느껴지긴 한다. 서비스와 개인 취향에 맞추어 변경하면 될 것이다.
targets의 경우에는 모니터링할 Spring 서버의 url을 적어주면 된다. 나의 경우에는 docker-compose로 네트워크 설정을 해 줄 거 기 때문에 DNS를 이용하여 간편하게 컨테이너 이름으로 처리하였다.
이제 설정 파일을 scp 명령어를 통해 ubuntu 서버로 옮겨 주었다.
scp -i .\blogwidget2.pem .\github-tistory-posting\prometheus.yml ubuntu@blogwidget.com:/home/ubuntu/prometheus.yml
나는 별도의 폴더는 필요 없어서 기본 폴더인 /home/ubuntu에 prometheus.yml 이름으로 옮겨주었다.
Prometheus Docker 설치
Window 환경에서 Prometheus를 테스트하고 싶으면 아래 공식 홈페이지를 이용하자.
이를 이용하면, Ubuntu 서버에 설치하지 않고도 Prometheus를 사용해 볼 수 있으니, Localhost로 테스트해 보는 것도 가능할 것이다.
나의 경우에는 이미 작동 중인 개인 프로젝트에서 메트릭 정보를 이용할 것이므로, Ubuntu 서버에서 Docker를 이용해 설치해 주었다.
$ docker pull prom/prometheus
기본적인 명령어는 위와 같고, Docker-compose를 사용 중이라면 위의 과정은 생략해도 된다.
Prometheus Docker-compose 설정
나는 Docker-compose를 사용 중이기 때문에 아래와 같이 Prometheus 부분을 추가해 주었다.
version: '3'
services:
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
depends_on:
- certbot
networks:
- monitor-network
prometheus:
image: prom/prometheus:latest
container_name: prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--web.external-url=/prometheus/'
volumes:
- /home/ubuntu/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
restart: always
networks:
- monitor-network
spring-blue:
container_name: spring-blue
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
networks:
- monitor-network
spring-green:
container_name: spring-green
build:
context: .
dockerfile: Dockerfile
ports:
- "8081:8080"
networks:
- monitor-network
networks:
monitor-network:
프로메테우스는 기본적으로 9090 포트를 사용하기 때문에, 이에 맞게 포트를 설정해 주고, 컨테이너 내부 설정 파일을 외부에서 간편하게 수정할 수 있도록 volumes를 통하여 마운트 해주었다. 또한, prometheus.yml에서 DNS로 설정을 해주었기 때문에 같은 networks를 이용하여 Spring과 Nginx, Prometheus를 연결해주고 있다.
Command 설정의 경우는 다음과 같으며, 설치 과정에서 만난 오류를 해결한 방법이다.
나와 다르게 설정을 진행한 경우에는 해당 내용은 추가하지 않아도 될 것이다.
--config.file=/etc/prometheus/prometheus.yml: Prometheus가 설정 파일의 위치를 명확히 알 수 있도록 지정한다.
--web.external-url=/prometheus/: 외부에서 접근할 때의 기본 URL을 설정한다.
Prometheus Nginx 설정
Prometheus의 기본 웹 대시보드에 접근하기 위해서는 기본적으로 Prometheus 컨테이너 내부에 접근하면 된다. 이를 위해 기본적으로 이 전에 설정한 포트를 포함하여 "http://<your-domain-or-ip>:9090" 이 기본 url일 것이다.
여기에 접근하기 위하여 Nginx 설정을 바꾸어 주자.
server {
listen 80;
server_name blogwidget.com;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name blogwidget.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/blogwidget.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blogwidget.com/privkey.pem;
location /prometheus/ { ## 추가된 부분
proxy_pass http://prometheus:9090/prometheus/; ## /prometheus/ 로 들어오는 요청을
proxy_set_header Host $host; ## prometheus 컨테이너로 리버스 프록시
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
proxy_pass http://spring-green:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
여기서 주의할 점!!
나의 경우에는 docker-compose에서 "--web.external-url=/prometheus/"를 사용하여 기본 url을 바꾸어 주었다. 따라서 prometheus:9090이라는 DNS뒤에 "--web.external-url=/prometheus/"에 설정한 /prometheus/ 가 추가 된 것에 유의하자!
기본적으로는 해당 부분을 지우고 9090으로 마무리 지으면 된다.
Prometheus 시작
Nginx까지 설정을 마쳤다면, 설정해 준 URL을 통해 Prometheus에 접근이 가능할 것이다.
첫 메인 화면은 아무런 설정이 없는 메인 화면이다.
여기서 Prometheus의 Expression(쿼리 창)에서는 PromQL(Prometheus Query Language)을 사용하여 다양한 메트릭을 조회하고, 분석 및 시각화할 수 있다.
PromQL이란 Prometheus에 수집된 메트릭 데이터를 조회, 집계, 필터링, 그리고 계산하는 데 사용되는 언어정도로 이해하면 된다.
처음으로 up을 치고 Execute를 눌러보자.
만약 Spring서버와 정상적으로 연결이 되었다면, blue 서버와 같이 1이 반환될 것이고, 연결이 되지 않았다면 green 서버와 같이 0이 반환될 것이다.
이는 상단 탭의 Status > Targets 메뉴에서 간편하게 확인도 가능하다.
Up으로 표시된 서버의 Endpoint부터 작동된 시간까지 정보를 한눈에 볼 수 있다.
만약 연결이 잘 안 되었다면, prometheus의 설정이 정확이 되었는지 다시 확인해 보길 바란다.
Prometheus 간단하게 사용해 보기
Prometheus에서 지원하는 PromQL는 아직 내게 너무 어색하다.
서칭을 통해 여러 가지 쿼리들을 실행해 보고 있으며, 사용법이 익숙해질 때쯤 포스팅을 업데이트하도록 하겠다.
아래는 여러 가지 시험 삼아 작동해 보았던 쿼리들이다.
1. scrape_samples_post_metric_relabeling : 각 타깃에서 수집한 메트릭의 개수
Prometheus가 각 타깃에서 수집한 메트릭의 개수를 나타낸다. 현재 표기 방식은 Table이며, green의 경우 down 서버이기에 0으로 표시된 것을 알 수 있다.
2. http_server_requests_seconds_sum : HTTP 요청의 총 응답 시간
HTTP 요청의 총 응답 시간을 나타낸다. 쿼리 작성부 및의 Graph를 클릭하면, 시간대 별로 쿼리의 응답값을 볼 수 있다. 하단의 정보를 통해 메서드 별로 보는 것도 가능하고, 시간대를 설정해서 보는 것도 가능하다.
3. jvm_memory_used_bytes : JVM에서 사용 중인 메모리 양
JVM에서 사용 중인 메모리 양을 조회하는 쿼리이다.
여기서 재밌는 점은 Eden Space, Survivor Space처럼 Heap영역도 다 표시된다는 점이고, Eden 영역이 치솟았다가 0으로 사라지는 모습은 Minor GC를 나타내는 모습이다.
4. 이 외
http_server_requests_seconds_count : Spring Boot Actuator에서 제공하는 HTTP 요청 수를 조회
jvm_memory_committed_bytes JVM에 할당된 총 메모리 크기를 조회
jvm_gc_pause_seconds_sum JVM에서 수행된 가비지 컬렉션에 소요된 총 시간
jvm_threads_live_threads 현재 실행 중인 JVM 쓰레드 수를 조회
process_uptime_seconds 애플리케이션이 얼마나 오래 실행되었는지 조회
이 외에는 위와 같은 쿼리들이 있으며, 모두 Spring Actuator에서 지원하는 부분들이다.
아쉽게도 내가 원하는 기능인 CPU 사용량 같은 건, Spring Actuator만으로는 지원하지 않는 기능으로 쿼리를 사용할 수 없다. 이를 사용할 수 있게 하려면 Node Exporter를 추가로 사용해야 한다고 한다.
이번 포스팅에서는 Prometheus를 Spring Actuator와 함께 사용하여 애플리케이션의 성능을 모니터링하는 방법을 알아보았다. Actuator를 통해 간편하게 메트릭을 노출하고, Prometheus가 이를 수집하여 실시간으로 분석하는 것을 웹 대시보드를 통해 간편하게 확인할 수 있었다.
아직 Prometheus에 대해 미숙하기 때문에, 여러 가지 기능들도 건드려보고 Node Exporter를 이용한 확장과 Grafana를 이용한 시각화 등 다양한 도전을 해 볼 예정이다.
요즘 아직도 취업 준비때문에 바쁜 일정을 보내고 있는데, 조금씩 시간을 내서 기술 스택도 더 넓히고, 블로그 관리도 꾸준히 할 계획이다. 모두 화이팅 하자.
'Spring > Project' 카테고리의 다른 글
[인증인가] Access Token, Refresh Token의 저장 위치에 대한 고찰 (1) | 2024.11.30 |
---|---|
[Java] CompletableFuture로 비동기 프로그래밍 구현하기 (10) | 2024.10.09 |
[Java] Object pooling(오브젝트 풀링) - Apache Commons Pool2로 구현하기 (2) | 2024.10.05 |
[Java] IntelliJ Profiler로 병목지점 찾아, Java ImageIO 성능 개선하기 (5) | 2024.10.03 |
[디자인 패턴] 전략 패턴(Strategy Pattern), 팩토리 패턴(Factory Pattern), 레지스트리 패턴(Registry Pattern) (0) | 2024.07.30 |