Quarkus项目Prometheus采集Metrics端点返回406错误求助
我有一个v3.8.1版本的Quarkus项目,已引入quarkus-micrometer和quarkus-micrometer-registry-prometheus扩展。使用Postman调用/q/metrics/prometheus端点返回200 OK,但Prometheus服务器采集该端点时返回406 Not Acceptable。
对比请求后确认,Prometheus采集请求携带的Accept头包含application/openmetrics-text,这是导致406错误的原因。需要找到解决方案,要么让端点兼容该请求头返回200,要么配置Prometheus不发送该头。
当前配置
application.yml
quarkus: micrometer: enabled: true export: prometheus: enabled: true path: metrics/prometheus
prometheus.yml
global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'quarkus-micrometer' metrics_path: '/q/metrics/prometheus' scrape_interval: 3s static_configs: - targets: ['MY_IP:8080']
方案一:让Quarkus支持application/openmetrics-text请求头
Quarkus的quarkus-micrometer-registry-prometheus扩展默认仅支持text/plain和application/vnd.google.protobuf(启用Protobuf时)的Accept头。要兼容application/openmetrics-text,可以通过自定义REST端点实现:
创建一个REST端点,复用原有路径,专门处理application/openmetrics-text类型的请求:
import io.micrometer.prometheus.PrometheusMeterRegistry; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; @Path("/q/metrics/prometheus") public class OpenMetricsEndpoint { @Inject PrometheusMeterRegistry registry; @GET @Produces("application/openmetrics-text; version=1.0.0; charset=utf-8") public String getOpenMetrics() { return registry.scrape(); } }
JAX-RS会根据请求的Accept头自动匹配对应的处理方法,这样Prometheus发送application/openmetrics-text请求时就能正常返回指标数据。
方案二:配置Prometheus不发送application/openmetrics-text请求头
直接修改Prometheus的采集配置,强制指定Accept头为text/plain,覆盖默认的请求头:
更新prometheus.yml中的quarkus-micrometer任务配置:
- job_name: 'quarkus-micrometer' metrics_path: '/q/metrics/prometheus' scrape_interval: 3s scrape_headers: Accept: 'text/plain' static_configs: - targets: ['MY_IP:8080']
添加scrape_headers字段后,Prometheus采集时会发送text/plain的Accept头,与Postman请求一致,端点将返回200 OK。
验证
修改配置后重启Quarkus和Prometheus,可通过以下方式验证:
- 查看Prometheus的Targets页面,确认
quarkus-micrometer任务状态为UP; - 用curl模拟Prometheus的请求:
# 方案一验证 curl -H "Accept: application/openmetrics-text" http://MY_IP:8080/q/metrics/prometheus # 方案二验证(此时Prometheus实际发送的是text/plain请求) curl -H "Accept: text/plain" http://MY_IP:8080/q/metrics/prometheus
内容的提问来源于stack exchange,提问作者michjea

