안녕하세요. 회사와 함께 성장하고 싶은 KOSE입니다.
이번 포스팅은 Spring의 Actuator를 살펴보고 Prometheus, Grafana를 연동하는 과정, 중요한 지표 등을 정리하고자 합니다.
1. Spring Actuator
Spring Actuator는 Spring Boot의 일부로, 프로덕션 준비 상태를 갖춘 애플리케이션을 만들 때 유용한 도구입니다.
Actuator를 사용하면, 애플리케이션의 여러 측면을 모니터링하고 관리할 수 있습니다.
Spring Actuator의 주요 기능
- 메트릭: 애플리케이션의 다양한 메트릭을 수집하고 조회할 수 있습니다. HTTP 요청 수, 처리 시간, 데이터베이스 사용량 등을 확인할 수 있습니다.
- 헬스 체크: 애플리케이션의 상태를 나타내는 health 정보를 제공합니다. 데이터베이스의 연결, 디스크 공간, 사용 중인 서비스 등을 확인할 수 있습니다.
- 환경 정보: 애플리케이션을 실행하는 데 사용하는 환경 변수, 시스템 프로퍼티, 구성 파일을 확인할 수 있습니다.
- 로그 관리: 애플리케이션의 로그 수준을 조회하거나 변경할 수 있습니다.
- 스레드 덤프: 톰캣에 실행 중인 스레드 정보를 확인할 수 있습니다.
- HTTP 추적: 최근 처리된 HTTP 요청의 트레이스 정보를 제공합니다.
스프링에서 actuator를 사용하기 위해서는 gradle.kts에 actuator 라이브러리를 추가해야 합니다.
implementation("org.springframework.boot:spring-boot-starter-actuator")
application.yml 에는 actuator에서 제공할 정보를 설정할 수 있습니다.
- management.endpoints.health.show-details: 헬스체크를 하는 것으로 always로 설정하면 모든 세부 정보가 표시됩니다.
- management.endpoints.web.exposure.include: 어떤 엔드포인트를 외부에 노출할 것인지 결정합니다.
- management.server.port: 액츄에이터의 포트를 설정하는 항목입니다.
여기서 스프링은 8080으로 동작하는데, 액츄에이터는 어떻게 9292로 동작할 수 있을까요?
SpringBoot의 내부 구조는, 여러 개의 EmbeddedServletContainer 인스턴스를 가질 수 있습니다
이를 통해 여러 개의 HTTP 서버를 동시에 운영할 수 있는 것입니다.
이를 바탕으로 localhost:9292/actuator/health를 요청하면 다음의 헬스체크를 할 수 있습니다.
헬스체크는 스프링부트의 정상 로드뿐만 아니라, DB 등 외부 의존성 커넥션 등도 헬스체크의 대상이 됩니다.
만약 하나라도 정상적인 응답이 오지 않는다면, status가 DOWN이 오게 됩니다.
2. Prometheus 활용하기
스프링 actuator를 활용할 때, 애플리케이션 상태와 메트릭스를 외부로 노출시킬 수 있습니다.
prometheus를 사용한다면, actuator가 제공하는 /acturator/prometheus 엔드포인트로 요청하여 prometheus가 수집할 수 있는
포맷으로 메트릭스를 제공받을 수 있습니다.
prometheus는 pull 기반 모니터링 시스템으로, 지정된 엔트포인트에 정기적으로 데이터를 끌어와서 데이터를 수집할 수 있습니다.
각 시스템, 설치한 방법에 따라 prometheus를 기동 하는 방법, prometheus의 설정 파일을 변경하는 방법이 다를 수 있습니다.
homebrew를 사용하는 경우는 다음의 방법으로 적용할 수 있습니다.
# prometheus 실행
brew services start prometheus
# 변경해야 하는 prometheus.yml 파일 위치
/opt/homebrew/etc
# 파일 변경하기
vim prometheus.yml
scrape_configs:
- job_name: "prometheus" # 첫 번째 작업의 이름은 "prometheus"
static_configs: # 이 작업에서 메트릭을 수집할 대상은 정적으로 정의
- targets: ["localhost:9090"] # Prometheus 자체 메트릭을 수집
- job_name: "spring-actuator" # 두 번째 작업의 이름은 "spring-actuator"
metrics_path: "/actuator/prometheus" # 스프링 부트 애플리케이션의 메트릭 엔드포인트를 설정
scrape_interval: 10s # 메트릭을 수집하는 간격은 10초
static_configs:
- targets: ["localhost:9292"] # 스프링 애플리케이션의 호스트와 포트를 정의
이와 같은 방법을 적용하면 프로메테우스를 활용하여 모니터링을 쓸 수 있습니다.
3. Grafana 연동
grafana는 다양한 모니터링 기능을 제공하여 prometheus에 연동하여,
사용자 친화적인 시각화 및 대시보드를 생성하여 처리할 수 있습니다.
그런데, spring actuator에서 grafana를 연동하지 않고 중간에 prometheus를 쓰는 이유는 무엇일까요?
- 확장성과 유연성: Prometheus는 스프링 및 서비스 인프라 등 메트릭을 수집할 수 있습니다. 이렇게 하여 하나의 중앙집중화된
위치에서 전체 시스템의 메트릭을 모니터링할 수 있습니다. - 데이터 처리 및 집계: Prometheus는 수집한 메트릭에 대해 강력한 쿼리 언어를 사용하여 데이터를 처리하고 집계할 수 있습니다.
이를 통해 평균 및 최대 최소 등과 같은 복잡한 계산을 수행할 수 있습니다. - 통합 생태계: Prometheus는 Grafana와 같은 다른 모니터링 툴과 잘 통합됩니다.
Grafana는 Prometheus와 같은 다양한 데이터 소스를 지원하며, 이를 통해 유연하게 대시보드를 구성할 수 있습니다.
grafana를 설치한 후, 기동하여 localhost:3000으로 이동하면 grafana를 사용할 수 있습니다.
grafana는 이미 잘 만들어진 대시보드가 있어서, 이를 임포트 하여 사용하면 하단처럼 대시보드를 만들 수 있습니다.
(https://grafana.com/grafana/dashboards/)
스프링을 사용하면 주로 확인해야 할 지표 등이 있습니다.
- Tomcat thread
- JVM Statistics Threads/Buffers
- CPU
- HikariCP Statistics
Tomcat thread
Tomcat thread는 grafana Query로 다음처럼 작성할 수 있습니다.
- tomcat_threads_config_max_threads: 스레드가 생성될 수 있는 최대 개수
- tomcat_threads_current_threads : 현재 스레드 풀에 존재하는 총 스레드 수
- tomcat_threads_busy_threads: 현재 처리 중인 요청의 수
현재 스레드풀이 10개이고, 최대 스레드 생성 가능한 개수가 200개라면 maxThreads 설정에 따라 동적으로 늘어날 수 있습니다.
만약 Current thread 풀에 근접하게 Busy thread가 동작하고 있다면 모니터링에 유의해야 합니다.
JVM
JVM은 GC, Heap 등 다양한 지표를 확인할 수 있습니다.
만약, 인메모리 기반으로 데이터를 저장하거나 세션과 같이 서버에 영향을 줄 수 있는 기능을 사용한다면
Heap 메모리 증가로 인해 GC가 동작할 수 있습니다.
CPU
반복적인 I/O나 복잡한 비즈니스 요청이 수행한다면 CPU가 비정상적으로 동작할 수 있습니다.
CPU usage를 통해 이러한 상황을 모니터링할 수 있습니다.
HikariCP Statistics
JPA나 JDBC를 사용하면 기본적으로 DB 커넥션을 열고 닫는 과정을 라이브러리가 잘 처리를 해줍니다.
만약 커넥션이 닫히지 않아서 Active DB 커넥션 개수가 총 커넥션 사이즈를 넘어가게 되면, 타임아웃이 증가하게 됩니다.
모니터링을 통해 만약 DB 커넥션 개수가 많이 필요하다면 DBCP 조절을 통해 가능합니다.
(DBCP 강의: https://www.youtube.com/watch?v=zowzVqx3MQ4)
그 외에도 많은 모니터링 지표가 있습니다.
남은 지표들도 추가로 작성해 나가며 정리하도록 하겠습니다!
읽어주셔서 감사합니다~!
참고: 영한님 스프링 핵심 원리 활용 https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%ED%95%B5%EC%8B%AC%EC%9B%90%EB%A6%AC-%ED%99%9C%EC%9A%A9