서버 모니터링 및 장애대응시 tomcat threadpool과 hikaricp 관련 메트릭은 중요한 요소다. (경험상 두 메트릭 지표 관련 장애를 몇번 겪었기에 더 뼈저리게 느끼고 있다)
이번 포스팅에선 AWS ECS 환경에서 스프링부트의 actuator 를 활용하여 DataDog 에 커스텀 메트릭을 연동했던 트러블슈팅 과정을 기록하고자 한다.
실제 적용된 접근 방법만 확인하고 싶으신분들은 ‘접근 방법3’으로 넘어가면 된다.
접근 방법1 - Datadog Agent 의 Prometheus Scrape 활용하기
위 방법은 실패하였다.
스프링부트 컨테이너가 io.micrometer:micrometer-registry-prometheus
의존성을 활용하여
/actuator/prometheus
엔드포인트로 prometheus 메트릭을 수집할 수 있도록 하고
dd-agent 컨테이너에서 지원되는 Prometheus Scrape 기능을 활용하여 주기적으로 수집하는 형태의 접근이었다. 하지만, 위 접근 방법을 통해 메트릭 수집까진 성공했지만 정상적으로 데이터까진 수집하지 못했다. (ex. hikaricp.connections.max 라는 메트릭을 스프링부트 컨테이너로부터 수집했지만 실제 값이 어떻게 되는지까진 수집되지 않았다.)
DevOps 팀에서 DataDog 지원팀으로 문의한 결과 Datadog Agent 의 Prometheus Scrape 기능은 쿠버네티스 환경에서만 적용 가능하며, AWS ECS 환경에서는 해당 기능은 적용 불가능하다고 전달받았다.
물론 공식문서에서도 쿠버네티스 환경을 기준으로 설명하고 있지만 필요한 설정만 하면 동일하게 동작하지 않을까 싶어 접근해보았었다. (LLM도 가능하다고 답변해줬는데 LLM의 갈길은 아직 멀었나보다..) 이와 관련하여 아래 레퍼런스들을 참고하면 좋다.
- https://www.datadoghq.com/blog/monitor-prometheus-metrics/
- https://docs.datadoghq.com/ko/containers/kubernetes/prometheus/?tab=kubernetesadv2
- https://docs.datadoghq.com/ko/containers/docker/prometheus/?tab=standard
접근 방법2 - 스프링 컨테이너에서 micrometer-registry-datadog 의존성 활용
위 방법은 채택하지 않았다
스프링 컨테이너에서 micrometer-registry-datadog 의존성을 활용하여 주기적으로 DataDog 중앙서버에 actuator 메트릭 정보를 HTTP 프로토콜로 송신하는 방법이다.
채택하지 않았던 이유는 ECS 서비스명, 클러스터명과 같은 환경에 종속적인값들을 환경변수로 주입받아 TAG 로 지정하여 데이터독 중앙서버에 송신하는 형태가 애플리케이션 관점에서 외부 환경을 알아야하는 측면에서 좋은 방향성은 아닐것 같단 생각이 들었다.
예를 들면, 쿠버네티스 환경으로 변경시 해당 값들은 불필요해지고 동일하게 수정을 해야될텐데 말이다.
이와 관련하여 아래 레퍼런스들을 참고하면 좋다.
- https://docs.micrometer.io/micrometer/reference/implementations/datadog.html
- https://medium.com/@chikim79/time-series-metrics-with-micrometer-on-aws-ecs-fargate-running-spring-boot-application-bdbf539dae3c
접근 방법3 - 스프링 컨테이너에서 StatsD를 활용하여 DD-AGENT 컨테이너에 주기적으로 Actuator 메트릭 송신
채택하여 적용한 방법이다.
statsd는 애플리케이션 메트릭을 수집/집계 후 전송하는데 사용되는 데몬 프로세스다.
DogStatsD는 DataDog에서 statsd를 자체적으로 구현한 커스텀 메트릭 수집 시스템이다. statsd 기본 스펙 뿐만 아니라 DataDog만의 추가 기능을 확장하였다.
실제 메트릭 수집 프로세스는 스프링 컨테이너가 주기적으로 사이드카 패턴으로 떠있는 데이터독 에이전트 컨테이너로 Actuator 메트릭을 전달하고, 데이터독 에이전트 컨테이너는 데이터독 중앙서버에 수집된 메트릭을 송신하게 된다.
실제 적용 과정은 간단하다.
적용 과정
1) 스프링부트 의존성 추가 및 application.yml 설정
1
2
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-statsd'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server:
tomcat:
mbeanregistry:
enabled: true # tomcat 스레드풀 모니터링을 위한 mbeanregistry 활성화, tomcat mbeanregistry 활성화시 힙메모리의 2MB를 차지하여 스프링부트는 기본적으로 비활성화 처리함
management:
server:
port: 6088 # 보안 포트 (외부에서 접근 불가하도록)
endpoints:
web:
exposure:
include:
- metrics
metrics:
enable:
all: false
hikaricp: true
tomcat.threads: true
statsd:
metrics:
export:
enabled: true
host: localhost # 같은 ECS 태스크 내부의 컨테이너들을 localhost 로 통신 가능
port: 8125 # 데이터독에서 공식지원하는 statsd 프로토콜을 위한 포트
flavor: datadog
step: 10s # 메트릭 전송 주기
protocol: upd # 디폴트값
프로토콜은 TCP
, UDP
, UDS_DATAGRAM
세 가지를 지원하며 디폴트는 UDP
로 되어있다.
StatsD가 UDP
통신을 선호하는 주요 이유는 다음과 같다.
성능상의 이점
- 빠른 처리 속도: TCP 와 달리 handshake 과정이 없어 오버헤드가 적음, 메트릭 전송 시 블로킹이 발생하지 않아 애플리케이션 성능에 미치는 영향이 최소화됨
- 낮은 리소스 사용: 상태를 유지할 필요가 없음
안정성과 독립성
- 애플리케이션과의 분리: 애플리케이션과 메트릭 수집이 완전히 분리되기에 StatsD 서버의 장애가 애플리케이션에 영향을 주지 않음
- 유연한 구성: 다른 언어로 작성되거나 다른 서버에서 실행되는 것이 가능, 샘플링을 통해 네트워크 사용량을 조절할 수 있음
2) taskdef.json 에 DataDog Agent 컨테이너 statsd 프로토콜 수신을 위한 포트 매핑 및 환경 변수 추가
참고로 DD_DOGSTATSD_ENABLED의 디폴트값은 true이고, DD_DOGSTATSD_PORT은 8125이다. 즉, 필수적인 요소는 아니기에 DogStatsD 서버의 포트 변경이 필요할때만 설정을 추가해주면 될것 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"containerDefinitions":
[
{
...
"portMappings":
[
...
{
"hostPort": 8125,
"protocol": "udp",
"containerPort": 8125
}
],
"environment":
[
...
{
"name": "DD_DOGSTATSD_ENABLED",
"value": "true"
},
{
"name": "DD_DOGSTATSD_PORT",
"value": "8125"
}
]
}
]
}
위 actuator 설정은 tomcat.threads, hikaricp 메트릭만 수집되도록 하였는데 제품 상황에 맞춰 팀 내부적인 논의를 바탕으로 커스텀하게 설정하면 된다. (데이터독에서 스프링부트 actuator를 통해 수집되는 메트릭은 커스텀 메트릭으로 간주되어 추가 비용이 발생할 수 있으니 참고하면 좋다)
위 적용을 통한 기대효과는 다음과 같다.
- 장애 원인 분석시 보조 지표 활용 -> Tomcat 활성 스레드가 최대치에 도달해 503 에러가 발생했는지, 혹은 HikariCP 커넥션 풀이 최대 상태를 얼마나 유지했는지
- 서버 스레드풀 및 hikaricp 설정 최적화
- 모니터링 알림을 통한 선제적 장애 대응