서비스를 운영 중에 다음과 같은 warning 로그를 모니터링하게 되었다.
warning 로그가 발생하고 있는 지점은 micrometer-core의 OnlyOnceLoggingDenyMeterFilter였다.
디버깅을 통해 확인해 본 결과, 직접 커스터마이징 한 필터 이후에 OnlyOnceLoggingDenyMeterFilter가 작동하며 Warning Message를 발생시키고 있던 것이다.
Reached the maximum number of URI tags for 'http.server.requests'가 발생한 원인과 해결법
http.server.requests 에러는 메트릭 시스템에서 URI 태그의 고유한 조합이 너무 많아질 경우 발생하는 에러다.
이는 주로 프로메테우스, 마이크로미터와 같은 모니터링 시스템이 애플리케이션의 HTTP 요청을 추적할 때 나타난다.
모니터링 시스템은 HTTP 요청을 구분하고 분석하기 위해 다양한 태그를 사용하는데 다음과 같은 태그들이 있다.
- method: GET, POST 등 HTTP 메소드
- status: 200. 404, 500 등 HTTP 상태 코드
- url: 요청 경로
이때 각 고유 URI는 별도의 태그 값으로 저장되어 메트릭을 더 세밀하게 분석할 수 있게 한다.
모니터링 시스템은 고유 URI 태그 조합들을 별개의 데이터로 저장하고 추적한다.
이러한 고유한 값이 많아지는 것을 "카디널리티가 높다"라고 표현하는데 Micrometer는 메트릭의 카디널리티를 제어하기 위해 URI 태그의 최대 개수를 제한한다.
메트릭의 카디널리티가 높아지면 메모리 사용량이 증가하고 프로메테우스와 같은 메트릭 시스템의 성능이 저하될 수 있기 때문이다.
application.yml에서 다음과 같이 URI 태그의 양을 수정할 수도 있다.
management:
metrics:
web:
server:
max-uri-tags: 200
애플리케이션이 실제로 100개 이상의 고유한 URI를 가지고 있는 경우, 서비스 규모에 맞게 늘려주는 것은 맞다.
하지만 앞서 언급한 바와 같이 URI 태그를 늘리게 되면 그만큼 메모리 사용량이 증가하여 근본적인 해결법이 아니다.
불필요한 URI 태그를 만드는 곳을 찾아 없애주는 게 중요하다.
문제의 원인은 커스터마이징 한 필터에 있었다.
필터의 우선순위는 다음과 같았다.
@Order(HIGHEST_PRECEDENCE + 1)
public class CustomFilter extends OncePerRequestFilter {
...
}
위와 같이 우선순위를 설정하게 되면 스프링 부트의 메트릭 수집 필터 WebMvcMetricsFilter와 정확히 동일한 순위를 가지게 된다.
CustomFilter와 WebMvcMetricsFilter가 우선순위가 동일하기 때문에 순서를 보장할 수 없게 되고
만약 CustomFilter가 먼저 실행되게 된다면 메트릭 필터의 URI 인식 기능에 문제를 일으킬 수 있다.
다음과 같이 수정하자.
@Order(LOWEST_PRECEDENCE - 10)
필터 순서를 뒤로 미뤄 WebMvcMetricsFilter와 서로 간섭하지 않고 독립적으로 실행할 수 있게 한다면 WebMvcMetricsFilter가 정상적으로 URI 템플릿을 인식하여 태그 카디널리티 문제를 해결할 수 있다.
'프로그래밍 > Java' 카테고리의 다른 글
Java 코드를 빌드할 수 있는 여러가지 방법 feat. jar, bootJar, shadowJar (0) | 2025.09.04 |
---|---|
Java에서 파일 MIME 구하기 feat. nio.file (0) | 2025.08.29 |
[Java] ModelMapper란? (0) | 2023.07.12 |
[Java] StringTokenizer에 대해 알아보자~ (0) | 2022.08.09 |
String vs (StringBuffer vs StringBuilder) (0) | 2022.06.07 |
댓글