文章目录
- [1. Spring MVC 指标](#1. Spring MVC 指标)
-
- [1.1 查看指标](#1.1 查看指标)
-
- [1.1.1 http.server.requests](#1.1.1 http.server.requests)
- [1.1.2 http.server.requests](#1.1.2 http.server.requests)
- [2.2 自定义指标名称](#2.2 自定义指标名称)
- [2.3 追加自定义标签](#2.3 追加自定义标签)
-
- [2.3.1 方式 1:追加标签](#2.3.1 方式 1:追加标签)
- [2.3.2 方式 2:完全替换全部标签](#2.3.2 方式 2:完全替换全部标签)
- [2.4 把已捕获异常埋入指标标签](#2.4 把已捕获异常埋入指标标签)
- [2.5 自定义过滤:跳过部分请求不采集指标](#2.5 自定义过滤:跳过部分请求不采集指标)
- [2. Spring WebFlux 指标](#2. Spring WebFlux 指标)
1. Spring MVC 指标
自动配置会对所有由 Spring MVC 控制器、函数式处理器处理的请求做指标埋点。默认生成指标名称为 http.server.requests。
1.1 查看指标
/actuator/metrics 包含两个指标名:
java
"http.server.requests",
"http.server.requests.active",
1.1.1 http.server.requests
基于 Micrometer Observation 生成的 HTTP 请求计时器指标,baseUnit 单位为 seconds(秒)。
返回示例:
json
{
"availableTags": [
{
"tag": "exception",
"values": [
"none"
]
},
{
"tag": "method",
"values": [
"GET"
]
},
{
"tag": "error",
"values": [
"none"
]
},
{
"tag": "uri",
"values": [
"/actuator/metrics/{requiredMetricName}",
"/actuator/metrics",
"/actuator/prometheus",
"/api/redis/{key}"
]
},
{
"tag": "outcome",
"values": [
"SUCCESS"
]
},
{
"tag": "status",
"values": [
"200"
]
}
],
"baseUnit": "seconds",
"measurements": [
{
"statistic": "COUNT",
"value": 117
},
{
"statistic": "TOTAL_TIME",
"value": 2.992938
},
{
"statistic": "MAX",
"value": 0.0297637
}
],
"name": "http.server.requests"
}
整体字段概览:
| 字段 | 说明 |
|---|---|
name |
指标名称:http.server.requests,服务端HTTP请求计时器 |
baseUnit |
基础单位:seconds 秒 |
availableTags |
该指标可用标签集合,代表会出现在 Prometheus 里的标签维度以及采样到的枚举值示例 |
measurements |
度量统计值:COUNT总请求数、TOTAL_TIME总耗时、MAX最大耗时 |
availableTags 标签解读:
| tag标签 | 示例values | 含义 |
|---|---|---|
exception |
none |
请求抛出的异常类名;none=无异常抛出 |
method |
GET |
HTTP 请求方法:GET/POST/PUT/DELETE... |
error |
none |
错误标识;none=业务无错误;发生异常时为异常类名 |
uri |
/actuator/metrics/{requiredMetricName} /actuator/metrics /actuator/prometheus /api/redis/{key} |
模板化URI,不是真实路径变量值,路径中的变量被大括号占位,防止标签爆炸 |
outcome |
SUCCESS |
请求结果枚举:SUCCESS/CLIENT_ERROR/SERVER_ERROR/REDIRECTION,由HTTP状态码推导 |
status |
200 |
HTTP响应状态码字符串,如 200、404、500 |
⚠️注意:
values只是当前采样看到的取值,不是全部枚举全集,是实例已经采集到的值。
measurements 度量数据:
| statistic统计类型 | value值 | 释义 |
|---|---|---|
COUNT |
117 | 总请求次数:一共117次http请求 |
TOTAL_TIME |
2.992938 | 全部请求累加总耗时,单位秒:117次请求合计耗时约2.99秒 |
MAX |
0.0297637 | 这一批采样窗口内最大单次请求耗时,约29.76毫秒 |
/metrics端点返回的是内存中快照;导出到 Prometheus 后会拆分为 3个指标:
http_server_requests_seconds_count请求计数http_server_requests_seconds_sum总耗时http_server_requests_seconds_max最大耗时
1.1.2 http.server.requests
活跃请求计时器指标 ,用于观测正在处理中尚未完成的 HTTP 请求 ,和普通 http.server.requests(已完成请求)是一对指标。
访问
/actuator/metrics/http.server.requests.active获取该快照,baseUnit: seconds单位为秒。
字段总览:
| 字段 | 说明 |
|---|---|
name |
http.server.requests.active,服务端活跃HTTP请求指标,跟踪运行中未结束请求 |
baseUnit |
seconds,时间单位:秒 |
availableTags |
可用标签集合,values为当前实例已经采集到的样本值 |
measurements |
度量统计:ACTIVE_TASKS活跃并发数、DURATION累计耗时、MAX最大处理时长 |
availableTags 标签解读:
| tag标签 | 示例values | 含义 |
|---|---|---|
exception |
none |
活跃请求发生异常;活跃阶段一般不会产生异常,几乎总是none |
method |
GET |
HTTP请求方法 |
uri |
UNKNOWN |
无法解析控制器映射模板时标记为UNKNOWN ;常见原因:404无匹配接口、过滤器提前拦截、静态资源、未走到控制器路由解析逻辑,会打uri=UNKNOWN标签,防止高基数标签爆炸 |
outcome |
SUCCESS |
请求处理结果;活跃请求该标签意义有限,最终结果要等请求结束看http.server.requests |
status |
200 |
HTTP响应码;活跃请求此时响应码还未完全确定,参考价值低 |
values仅代表当前已经观测到的值,不是全部枚举集合。
⚠️重点:uri=UNKNOWN,请求还没匹配到控制器模板就已经结束/被拦截,拿不到模板URI,就会标记为UNKNOWN。比如404、filter直接response返回、静态资源、网关层提前终止请求。
measurements 统计值解读:
| statistic统计类型 | value | 释义 |
|---|---|---|
ACTIVE_TASKS |
1 | 当前并发活跃请求数:此刻有1个HTTP请求正在处理中,还未返回响应 |
DURATION |
0.0024552 | 所有已完成的活跃任务的累计总耗时(秒) |
MAX |
0.002476 | 观测周期内,活跃请求曾经出现过的最大处理耗时,约2.476毫秒 |
和普通 http.server.requests 的核心区别:
| 指标 | 用途 | 统计的请求 | 主要统计项 |
|---|---|---|---|
http.server.requests |
已完成请求统计 | 请求处理完毕(成功/异常) | COUNT、TOTAL_TIME、MAX;用于QPS、延迟、错误率 |
http.server.requests.active |
活跃并发观测 | 正在运行、还没结束的请求 | ACTIVE_TASKS(并发数)、DURATION、MAX;用于观测瞬时并发、慢请求堆积 |
导出到 Prometheus 会生成下面几组时序:
text
http_server_requests_active_seconds_active_tasks 1
http_server_requests_active_seconds_duration_sum 0.0024552
http_server_requests_active_seconds_max 0.002476
2.2 自定义指标名称
你可以通过配置 management.observations.http.server.requests.name 属性来自定义该指标名称。
示例:
yml
management:
observations:
http:
server:
requests:
name: myapp.http.server.requests
配置完成后:
- 原
http.server.requests→ 变为myapp.http.server.requests - 原
http.server.requests.active→ 自动变为myapp.http.server.requests.active Actuator端点访问地址随之变化:/actuator/metrics/myapp.http.server.requests/actuator/metrics/myapp.http.server.requests.active
Prometheus 导出的指标名也同步变更:
text
myapp_http_server_requests_seconds_count
myapp_http_server_requests_seconds_sum
myapp_http_server_requests_seconds_max
myapp_http_server_requests_active_seconds_active_tasks
2.3 追加自定义标签
2.3.1 方式 1:追加标签
想要在默认标签基础上追加自定义标签,可以注册一个 @Bean,继承 org.springframework.http.server.observation 包下的 DefaultServerRequestObservationConvention。
代码示例:
java
@Component
public class CustomAddTagServerObservationConvention extends DefaultServerRequestObservationConvention {
@Override
public Iterable<KeyValue> getLowCardinalityKeyValues(ServerRequestObservationContext context) {
// 拿到默认全部标签
Iterable<KeyValue> defaultKeyValues = super.getLowCardinalityKeyValues(context);
Observation.ObservationView observation = context.getObservation();
return () -> {
var defaultIterator = defaultKeyValues.iterator();
return new java.util.Iterator<>() {
private boolean customTagAdded = false;
@Override
public boolean hasNext() {
return defaultIterator.hasNext() || !customTagAdded;
}
@Override
public KeyValue next() {
if (defaultIterator.hasNext()) {
return defaultIterator.next();
}
if (!customTagAdded) {
customTagAdded = true;
// 追加自定义低基数标签,业务维度,例如环境、app、traceEnv
return KeyValue.of("app_env", "prod");
}
throw new java.util.NoSuchElementException();
}
};
};
}
}
效果:
http.server.requests指标标签 = 默认全套标签 +app_env=prod。
2.3.2 方式 2:完全替换全部标签
想要完全替换默认标签,可以注册一个实现 ServerRequestObservationConvention 接口的 @Bean。
代码示例:
java
@Component
public class FullReplaceServerObservationConvention implements ServerRequestObservationConvention {
@Override
public String getName() {
// 指标名称,优先级低于配置 management.observations.http.server.requests.name
return "http.server.requests";
}
@Override
public Iterable<KeyValue> getLowCardinalityKeyValues(ServerRequestObservationContext context) {
// 完全自己构造标签集合,没有父类默认标签!
return java.util.List.of(
KeyValue.of("http_method", context.getCarrier().getMethod()),
KeyValue.of("http_status", String.valueOf(context.getResponse().getStatus())),
KeyValue.of("biz_app", "demo‑service")
);
}
@Override
public Iterable<KeyValue> getHighCardinalityKeyValues(ServerRequestObservationContext context) {
// 高基数标签(一般放traceId,不做metrics聚合)
return java.util.List.of();
}
}
2.4 把已捕获异常埋入指标标签
部分场景中,Web 控制器内部已经 try‑catch 捕获并处理掉的异常,不会自动填充到 http.server.requests 的 exception 指标标签上。
应用可以手动开启该行为:把捕获到的异常存入 请求属性(request attribute) ,Observation 过滤器就会读取该属性,把异常写入指标标签。
需要设置请求属性:ServerRequestObservationContext.CURRENT_EXCEPTION_ATTRIBUTE
代码示例:
java
@RestController
public class DemoController {
@GetMapping("/demo")
public String demo(HttpServletRequest request) {
try {
throw new RuntimeException("业务自定义异常");
} catch (RuntimeException e) {
// 关键:将捕获处理过的异常放入request属性,observation过滤器读取此属性
request.setAttribute(ServerRequestObservationContext.CURRENT_EXCEPTION_ATTRIBUTE, e);
return "业务降级返回";
}
}
}
2.5 自定义过滤:跳过部分请求不采集指标
默认采集全部 HTTP 请求。如果需要自定义请求过滤逻辑(跳过某些请求不采集指标),注册一个 FilterRegistrationBean<ServerHttpObservationFilter> 类型的 @Bean。
ServerHttpObservationFilter 是生成 http.server.requests 的核心过滤器。
通过 FilterRegistrationBean 可以设置:过滤匹配模式、排除路径、顺序。
代码示例:
java
@Configuration
public class ObservationFilterConfig {
@Bean
public FilterRegistrationBean<ServerHttpObservationFilter> observationFilterRegistration(ServerHttpObservationFilter filter) {
FilterRegistrationBean<ServerHttpObservationFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(filter);
// 只匹配 /api/**,其余路径不采集指标;也可以 setUrlPatterns、addUrlPatterns
registration.addUrlPatterns("/api/*");
// 设置过滤器顺序
registration.setOrder(1);
return registration;
}
}
⚠️注意:不是实现
FilterRegistrationBean,是构造FilterRegistrationBean<ServerHttpObservationFilter>的Bean,设置它的注册参数。不要自己new新Filter。
上面是白名单;如果要做黑名单(排除某些路径),上面这种 URL pattern 方式能力有限。
更灵活方案:自定义 ServerRequestObservationConvention,或者自定义ObservationPredicate,在 Observation 层面跳过观测。
java
@Configuration
public class ObsPredicateConfig {
@Bean
public ObservationPredicate observationPredicate() {
return (name, context) -> {
// http.server.requests 并且路径以 /actuator 开头,则不生成观测
if ("http.server.requests".equals(name) && context instanceof org.springframework.http.server.observation.ServerRequestObservationContext ctx) {
String path = ctx.getCarrier().getRequestURI();
return !path.startsWith("/actuator");
}
return true;
};
}
}
ObservationPredicate:全局开关,返回false代表不创建该Observation,完全不产生指标 ,比Filter粒度更精准。
2. Spring WebFlux 指标
和
Spring MVC指标基本一致,就不赘述了!!!
自动配置会对所有由 Spring WebFlux 控制器、函数式处理器处理的请求做指标埋点。默认生成指标名称为 http.server.requests。你可以通过配置 management.observations.http.server.requests.name 属性来自定义该指标名称。
想要在默认标签基础上追加自定义标签,可以注册一个 @Bean,继承 org.springframework.http.server.reactive.observation 包下的 DefaultServerRequestObservationConvention。
想要完全替换默认标签,可以注册一个实现 ServerRequestObservationConvention 接口的 @Bean。
部分场景下,控制器与函数式处理器内部捕获处理过的异常,不会作为请求指标的标签被记录。应用可选择开启该能力:将已处理的异常设置为请求属性,即可把异常记录进指标。