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

SpringBoot应用中如何统计控制器端点近10天的调用次数?

统计Spring Boot端点近X天调用次数的几种实现方式

默认Actuator的metrics只能提供累计调用次数,要实现按时间窗口(比如近10天)统计,可从以下几个方向入手:

1. 基于Micrometer扩展时间维度统计

Micrometer是Spring Boot Metrics的底层实现,我们可以给指标加上时间标签,或按时间维度拆分指标:

方式1:按日期拆分Counter

每天创建带日期标签的Counter,统计当日调用次数,查询时累加近X天的Counter值:

@Component
public class DailyEndpointCounter {
    private final MeterRegistry meterRegistry;

    public DailyEndpointCounter(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }

    public void incrementEndpointCall(String endpoint) {
        String today = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        Counter.builder("endpoint.daily.requests")
                .tag("endpoint", endpoint)
                .tag("date", today)
                .register(meterRegistry)
                .increment();
    }
}

在拦截器里调用计数方法,查询时遍历近X天的日期标签累加数值:

public long getTotalRequestsInLastXDays(String endpoint, int days) {
    long total = 0;
    LocalDate current = LocalDate.now();
    for (int i = 0; i < days; i++) {
        String date = current.minusDays(i).format(DateTimeFormatter.ISO_LOCAL_DATE);
        Counter counter = meterRegistry.find("endpoint.daily.requests")
                .tags("endpoint", endpoint, "date", date)
                .counter();
        if (counter != null) {
            total += counter.count();
        }
    }
    return total;
}

方式2:结合时序存储的Timer记录

用Timer记录请求时间戳,将指标导出到InfluxDB、Prometheus等时序数据库,直接通过存储的查询语法过滤时间范围统计。比如PromQL查询近10天的端点调用次数:

sum(increase(endpoint.requests_count{endpoint="/api/user"}[10d]))

2. 自定义AOP + 持久化存储

如果需要保留调用明细或更精确的统计,用AOP拦截控制器请求,把调用记录存入数据库,再通过SQL查询时间范围:

步骤1:编写AOP切面

@Aspect
@Component
public class EndpointCallAspect {
    private final EndpointCallRepository repository;

    public EndpointCallAspect(EndpointCallRepository repository) {
        this.repository = repository;
    }

    @Around("execution(* com.yourpackage.controller..*(..))")
    public Object logEndpointCall(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String endpoint = attributes.getRequest().getRequestURI();
        
        EndpointCallRecord record = new EndpointCallRecord();
        record.setEndpoint(endpoint);
        record.setCallTime(LocalDateTime.now());
        repository.save(record);
        
        return joinPoint.proceed();
    }
}

步骤2:实体类与Repository

@Entity
public class EndpointCallRecord {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String endpoint;
    private LocalDateTime callTime;
    // 省略getter/setter
}

public interface EndpointCallRepository extends JpaRepository<EndpointCallRecord, Long> {
    long countByEndpointAndCallTimeAfter(String endpoint, LocalDateTime startTime);
}

步骤3:查询近X天次数

public long getEndpointCallsInLastXDays(String endpoint, int days) {
    LocalDateTime startTime = LocalDateTime.now().minusDays(days);
    return endpointCallRepository.countByEndpointAndCallTimeAfter(endpoint, startTime);
}

3. 网关层统一统计(若用Spring Cloud Gateway)

如果服务有网关,可在网关添加全局过滤器,统一记录所有请求的端点和时间,再通过存储查询统计,无需每个服务单独实现:

@Component
public class EndpointCallFilter implements GlobalFilter, Ordered {
    private final EndpointCallRepository repository;

    public EndpointCallFilter(EndpointCallRepository repository) {
        this.repository = repository;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String endpoint = exchange.getRequest().getPath().value();
        EndpointCallRecord record = new EndpointCallRecord();
        record.setEndpoint(endpoint);
        record.setCallTime(LocalDateTime.now());
        repository.save(record);
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

内容的提问来源于stack exchange,提问作者pixel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 10:12:53