You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Prometheus绘制指定API端点的单次请求耗时?

问题描述

我在Spring Boot的API路由上添加@Timed注解,想要在Prometheus中统计API端点的响应耗时,但遇到以下问题:

  1. 未调用/ping或/pong接口时,http://localhost:8080/actuator/prometheus中看不到对应指标,只有调用至少一次后才会出现
  2. 执行PromQL查询(如rate(http_server_requests_seconds_sum{uri="/ping"}[5m])/rate(http_server_requests_seconds_count{uri="/ping"}[5m])、http_server_requests_seconds_sum{uri="/ping"})时,返回Empty query result

相关代码与配置

RestController代码

import io.micrometer.core.annotation.Timed;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/ping")
    @Timed(value = "ping.request.time", description = "time pIng")
    public String ping(){
        return "pIng";
    }

    @GetMapping("/pong")
    @Timed(value = "pong.request.time", description = "time pOng")
    public String pong(){
        return "pOng";
    }
}

Prometheus配置文件prometheus.yaml

global:
  scrape_interval:     15s # Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.

rule_files:
# - "first_rules.yml"
# - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
scrape_configs:
  - job_name: 'prometheus'

    static_configs:
      - targets: ['127.0.0.1:9090']

  - job_name: 'spring-actuator'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['SYSTEM_IP_ADDRESS:8080'] # refer system ip address rather that localhost

Prometheus启动命令

docker run -d --name=prometheus -p 9090:9090 -v C:\Users\Admin\Desktop\prometheus-test\prometheus.yaml:/etc/prometheus/prometheus.yml prom/prometheus --config.file=/etc/prometheus/prometheus.yml

解决方案

1. 解决指标未调用不显示的问题

Micrometer默认采用懒加载机制,只有接口被调用后才会生成对应时间序列。如果需要接口未被调用时也能看到指标,可以通过配置预初始化指标:

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MeterConfig {

    @Bean
    public ApplicationRunner initMeters(MeterRegistry registry) {
        return args -> {
            // 预初始化ping和pong的Timer指标
            Timer.builder("ping.request.time")
                    .description("time pIng")
                    .register(registry);
            Timer.builder("pong.request.time")
                    .description("time pOng")
                    .register(registry);
        };
    }
}

2. 解决PromQL查询返回空的问题

确认Prometheus抓取状态

  • 访问http://localhost:9090/targets,检查spring-actuator任务状态是否为UP,确保目标IP、抓取路径配置正确
  • 在http://localhost:9090/graph执行http_server_requests_seconds_count查询,确认是否存在带uri="/ping"标签的时间序列

检查标签匹配准确性

  • 从/actuator/prometheus端点复制uri标签的准确值(注意大小写、是否存在路径替换),确保查询时标签完全匹配
  • 可尝试模糊匹配排查:http_server_requests_seconds_count{uri=~".*ping.*"}

调整rate函数时间范围

rate()需要时间范围内至少两个样本才能计算结果,若接口调用频率低:

  • 缩短时间范围,比如将[5m]改为[1m]
  • 多次调用/ping接口,等待至少两次Prometheus抓取(抓取间隔5s,需等待10s以上)后再查询

3. 绘制单次请求耗时的正确PromQL

  • 查看最近一次请求的耗时:http_server_requests_seconds_max{uri="/ping"}
  • 查看请求耗时的分位值(如95分位):http_server_requests_seconds{uri="/ping",quantile="0.95"}
  • 计算一段时间内的平均耗时(需足够样本):sum(rate(http_server_requests_seconds_sum{uri="/ping"}[1m])) / sum(rate(http_server_requests_seconds_count{uri="/ping"}[1m]))

内容的提问来源于stack exchange,提问作者Maifee Ul Asad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:19:59