개요
까비에서는 프로메테우스와 그라파나, 핀포인트를 활용한 모니터링 시스템을 활용하여 서버 운영을 하고 있어요.
핀포인트에 대한 글은 우주님이 이미 작성해주셔서, 오늘은 Spring Actuator를 활용한 프로메테우스와 그라파나 기반 모니터링 시스템에 대해서 알아보도록 하겠습니다!
마이크로미터란?
모니터링 시스템을 구축하기 위해서는 모니터링의 대상이 되는 서버의 메트릭(측정 지표) 정보를 시각화하여 보여주는 대시보드가 필요해요.
모니터링 도구를 사용할 때, 각 대시보드가 요구하는 형식에 맞는 메트릭 데이터가 필요합니다. 예를 들어, 대표적인 모니터링 대시보드 라이브러리 중 하나인 그라파나라는 도구를 사용한다고 해봅시다. 그렇다면 그라파나가 인식할 수 있는 데이터 형식으로 정보를 전송해야 해요.
그런데 만약 모니터링 대시보드를 그라파나가 아닌 다른 대시보드로 변경하고자 한다면, 변경할 대시보드가 인식할 수 있는 데이터 형식으로 변환해주어야 하기 때문에 API를 전체적으로 수정해야 하는 번거로움이 생기게 될 것 입니다.
여기서 마이크로미터(Micrometer)의 역할이 중요해져요..! 마이크로미터는 표준화된 측정 방식을 제공하여, 다양한 모니터링 도구들 사이에서도 일관된 데이터를 제공할 수 있도록 해주는 일종의 인터페이스 역할을 수행합니다.
다양한 마이크로미터 구현체들이 존재하기 때문에 대부분의 대시보드 라이브러리에서는 마이크로미터 구현체를 하나 선택할 수 있도록 제공하고 있어요.
덕분에 API를 변경하지 않고 다른 대시보드로 쉽게 전환할 수 있어요!
자바 개발을 하신 분이라면 slf4j 라는 라이브러리를 떠올리면 쉽게 이해하실 수 있을 거예요.
로깅에 대한 인터페이스를 제공해주기 때문에 이 인터페이스를 구현하는 로그 라이브러리를 사용하고 있다면 소스코드를 변경하지 않고도 쉽게 다른 라이브러리로 변경할 수 있어요.
이런 특성 때문에 마이크로미터는 애플리케이션 메트릭 파사드(Application Metrics Facade)라고도 불러요.
마이크로미터의 구현체로는 대표적으로 다음과 같은 도구들이 있어요.
•
AppOptics
•
Atlas
•
CloudWatch
•
Elastic
•
JMX
•
Prometheus (오늘 알아볼 도구입니다!)
스프링 액추에이터란?
스프링 액추에이터(Spring Actuator)는 스프링 부트 프로젝트에서 제공하는 모니터링과 관리 기능을 포함한 라이브러리입니다. 마이크로미터를 내장하여 이를 통해 운영상에 필요한 지표들을 엔드포인트로 노출시킬 수 있도록 지원해줍니다. 이를 통해 개발자는 스프링 애플리케이션의 다양한 메트릭 정보들(jvm, heap memory, db connection 등)을 쉽게 얻을 수 있어요.
액추에이터에서는 애플리케이션의 메트릭 정보에 대한 추상화를 직접 제공해주기도 하지만, 마이크로미터 구현체를 사용하여, 그 구현체에 맞는 지표를 제공해주기도 해요.
액추에이터에서 마이크로미터 사용 방법
Micrometer 설정
스프링 부트 애플리케이션에서 마이크로미터를 사용하기 위해서는 우선 micrometer-core 의존성을 프로젝트에 추가해야 해요. 이 의존성을 추가하면, 스프링 부트 액추에이터가 자동으로 마이크로미터를 통해 수집 가능한 모든 기본 지표들을 활성화하고 구성합니다.
MeterRegistry
MeterRegistry는 마이크로미터의 핵심 컴포넌트로, 모든 메트릭의 등록 및 관리가 이루어지는 곳입니다. 스프링 부트 환경에서는 MeterRegistry가 자동으로 빈으로 등록되어, @Autowired나 생성자 주입을 통해 어디서든 사용할 수 있어요.
마이크로미터의 주요 메트릭 유형
1. 카운터 (Counter)
카운터는 단조롭게만 증가하는 단일 누적 측정값을 나타내며, 감소하는 동작은 지원하지 않아요. 주로 이벤트의 발생 횟수를 추적할 때 사용돼요. 예를 들어 HTTP 요청의 수를 카운팅하는 데 사용할 수 있어요.
@Autowired
private MeterRegistry registry;
public void recordEvent() {
Counter counter = registry.counter("events_occurred", "type", "event_type");
counter.increment();
}
Java
복사
이 코드는 이벤트가 발생할 때마다 카운터를 증가시킵니다. 여기서 "type"은 태그의 키이며, "event_type"은 해당 이벤트의 유형을 나타내요.
2. 게이지 (Gauge)
게이지는 어떤 값의 현재 수준을 측정하는 데 사용되는 메트릭입니다. 게이지는 값이 증가하거나 감소할 수 있으며, 메모리 사용량, 대기 중인 작업의 수, 혹은 현재 온도 같은 변동하는 값을 실시간으로 모니터링하는 데 적합해요.
@Autowired
private MeterRegistry registry;
private List<String> list = new ArrayList<>();
public void modifyList(String element, boolean add) {
if (add) {
list.add(element);
} else {
list.remove(element);
}
Gauge.builder("list_size", list, List::size)
.register(registry);
}
Java
복사
이 코드는 리스트의 현재 크기를 게이지로 모니터링합니다. 요소가 추가되거나 제거될 때마다 리스트의 크기를 반영해줍니다.
3. 타이머 (Timer)
타이머는 작업 실행에 걸리는 시간을 측정하는 메트릭입니다. 타이머는 요청 처리 시간, 배치 작업 실행 시간 등을 측정하는 데 사용되며, 이를 통해 애플리케이션의 성능을 분석할 수 있어요.
@Autowired
private MeterRegistry registry;
public void processTask() {
Timer timer = Timer.builder("task_duration")
.tags("task", "database_query")
.register(registry);
// Timer.Sample은 타이머를 시작합니다.
Timer.Sample sample = Timer.start(registry);
// 실제 작업을 수행합니다.
performTask();
// 작업이 완료되면 타이머를 정지하고 기록합니다.
sample.stop(timer);
}
Java
복사
이 코드는 performTask 메서드의 실행 시간을 측정합니다. Timer.Sample 객체를 사용하여 타이머를 시작하고 작업이 완료되면 정지하여 그 시간을 기록합니다.
프로메테우스란?
그렇다면 앞에서 언급된 프로메테우스는 정확히 무엇일까요?
메트릭은 그 순간의 데이터만을 제공하기 때문에 이 데이터의 시계열적 추적을 위해서는 데이터베이스에 메트릭을 지속적으로 저장해야 해요.
프로메테우스는 이 역할을 수행하는 도구로, 애플리케이션에서 생성된 메트릭을 주기적으로 수집하여 자체 DB에 저장해줍니다.
1.
이를 위해서는 애플리케이션에서 프로메테우스가 읽을 수 있는 형태로 메트릭을 엔드포인트로 노출시켜야 하고
2.
프로메테우스에서 엔드포인트로 GET 요청을 날려 메트릭 정보를 주기적으로 수집해야 해요.
그렇다면 개발자가 직접 프로메테우스가 이해할 수 있는 언어로 바꿔주어야 할까요?
마이크로미터-프로메테우스 구현체를 이용한 액추에이터 활용
•
spring-boot-starter-actuator
•
micrometer-core
•
micrometer-registry-prometheus
까비에서는 마이크로미터-프로메테우스 구현체를 사용하고 있어요.
이런식으로 의존성을 추가하고, 설정값들을 넣으면 스프링 부트에서 설정값들을 토대로 마이크로미터-프로메테우스 구현체를 자동으로 빈에 등록해줍니다.
덕분에 개발자는 소스코드를 직접 작성하지 않고도 손쉽게 프로메테우스에서 읽을 수 있는 형태로 메트릭 정보를 얻어볼 수 있어요.
이런식으로 설정을 하면 [address]:[port]/actuator 경로에서 메트릭 정보를 얻을 수 있어요.
설정을 통해 포트번호와 경로는 변경할 수 있습니다.
사진처럼 include: “*”로 지정하면 서버의 모든 메트릭 정보를 노출시키기 때문에, 만약 퍼블릭 환경이라면 절대로 이 설정을 사용하면 안됩니다…!!
Spring Actuator 보안 사고 이슈 & 해결
그렇지 않으면 이런 보안 사고가 발생할 수 있어요…
/actuator 경로에서 노출된 메트릭 정보의 주소들을 확인할 수 있어요.
/actuator/prometheus 경로에서 프로메테우스에서 읽을 수 있는 형태의 지표를 확인할 수 있어요.
그라파나란?
앞서서 프로메테우스가 메트릭 데이터를 주기적으로 수집하여 저장하는 DB 역할을 수행한다고 했었어요.
그라파나는 이 데이터를 사용하여 사용자 친화적인 대시보드를 제공해주는 라이브러리입니다.
그라파나는 프로메테우스 DB의 자체 쿼리 언어인 PromQL을 사용하여 프로메테우스 DB에서 데이터를 조회하고, 이를 GUI로 시각화하여 보여줍니다.
물론 프로메테우스 뿐만 아니라 다양한 데이터 소스를 지원해주기 때문에 입맛에 맞는 데이터 소스를 선택하면 돼요!
전체 플로우
1.
마이크로미터라는 표준 메트릭 인터페이스가 있고, 이에 대한 여러 구현체가 존재
2.
스프링 부트 액추에이터는 마이크로미터 메트릭을 자동으로 생성
→ 마이크로미터-프로메테우스 구현체는 프로메테우스가 읽을 수 있는 형태로 메트릭을 변환
3.
프로메테우스는 이렇게 만들어진 메트릭을 지속적으로 수집하여 내부 DB에 저장
4.
그라파나는 프로메테우스에 저장된 메트릭 데이터를 PromQL이라는 자체 쿼리 언어를 이용하여 조회하여, GUI 형태로 제공
마치며
지금까지 마이크로미터, 스프링 액추에이터, 프로메테우스, 그라파나를 활용한 모니터링 시스템의 구축에 대해 알아보았어요.
특히 마이크로미터를 중심으로 어떻게 다양한 모니터링 도구와의 호환성을 보장하면서도 유연하게 메트릭을 관리하고 수집할 수 있는지 살펴보았어요. 스프링 액추에이터의 강력한 통합 기능을 통해 이 모든 과정을 간소화하고, 프로메테우스와 그라파나로 이어지는 흐름을 손쉽게 구성할 수 있었어요!
이를 구성하는 방법에 대해서는 사난님께서 정리하신 글이 있으니 참고하시면 좋을 것 같아요.