SpringBoot 实现QPS监控:别等系统宕机了才知道加监控
引言:为什么我们需要QPS监控?
系统运行得好好的,突然收到告警,CPU 100%,接口大量超时,用户疯狂投诉。你赶紧打开监控面板一看,QPS已经飙升到平时的10倍,而你之前根本没关注过这个指标。等你手忙脚乱地排查问题、扩容服务时,系统已经宕机了,老板在群里催着问情况...
这种场景在我们开发过程中并不少见。很多团队在系统上线初期,往往只关注功能实现,忽略了监控体系建设,直到系统真正出问题时才后悔莫及。
今天,我们就来聊聊如何用SpringBoot实现QPS监控,让系统运行状态尽在掌握,别等系统宕机了才知道加监控的重要性。
QPS监控架构与组件
QPS(Queries Per Second)即每秒查询率,是衡量系统性能的重要指标之一。在SpringBoot中实现QPS监控,主要涉及以下几个核心组件:
- 指标收集器:负责收集请求数据
- 计数器:统计单位时间内的请求数
- 存储器:临时存储统计数据
- 展示层:可视化展示监控数据
- 告警器:超过阈值时发送告警
实现方案与技术选型
方案一:使用Micrometer + Prometheus
Micrometer是SpringBoot官方推荐的指标收集库,与Prometheus结合可以实现强大的监控能力。
首先添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
配置application.yml:
management:
endpoints:
web:
exposure:
include: prometheus,health,info
metrics:
export:
prometheus:
enabled: true
方案二:自定义拦截器实现
如果需要更细粒度的控制,可以使用自定义拦截器:
@Component
public class QpsInterceptor implements HandlerInterceptor {
private final MeterRegistry meterRegistry;
private final Counter requestCounter;
private final Timer requestTimer;
public QpsInterceptor(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.requestCounter = Counter.builder("http_requests_total")
.description("Total number of HTTP requests")
.register(meterRegistry);
this.requestTimer = Timer.builder("http_request_duration_seconds")
.description("HTTP request duration")
.register(meterRegistry);
}
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
requestCounter.increment();
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) throws Exception {
Timer.Sample sample = (Timer.Sample) request.getAttribute("timer_sample");
if (sample != null) {
sample.stop(requestTimer);
}
}
}
方案三:使用AOP切面统计
对于特定方法的QPS统计,可以使用AOP切面:
@Aspect
@Component
public class QpsAspect {
private final MeterRegistry meterRegistry;
private final Map<String, Counter> methodCounters = new ConcurrentHashMap<>();
public QpsAspect(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@Around("@annotation(trackQps)")
public Object trackQps(ProceedingJoinPoint joinPoint, TrackQps trackQps) throws Throwable {
String methodName = joinPoint.getSignature().getName();
Counter counter = methodCounters.computeIfAbsent(
methodName,
k -> Counter.builder("method_calls_total")
.tag("method", k)
.description("Number of method calls")
.register(meterRegistry)
);
counter.increment();
return joinPoint.proceed();
}
}
实际应用案例
案例一:API网关QPS监控
在API网关中,我们可以统计所有经过网关的请求:
@RestController
public class GatewayController {
private final MeterRegistry meterRegistry;
public GatewayController(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@GetMapping("/gateway/monitor")
public ResponseEntity<Map<String, Object>> getQpsMetrics() {
Map<String, Object> result = new HashMap<>();
// 获取QPS指标
Gauge qpsGauge = meterRegistry.find("http_requests_total").gauge();
if (qpsGauge != null) {
result.put("qps", qpsGauge.value());
}
// 获取请求延迟指标
Timer.Sample sample = meterRegistry.find("http_request_duration_seconds").timer();
if (sample != null) {
result.put("avg_response_time", sample.mean());
}
return ResponseEntity.ok(result);
}
}
案例二:业务方法QPS监控
对核心业务方法进行QPS监控:
@Service
public class OrderService {
private final MeterRegistry meterRegistry;
private final Timer orderProcessingTimer;
public OrderService(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.orderProcessingTimer = Timer.builder("order_processing_duration_seconds")
.description("Order processing duration")
.register(meterRegistry);
}
public Order createOrder(OrderRequest request) {
return orderProcessingTimer.record(() -> {
// 订单处理逻辑
return processOrder(request);
});
}
private Order processOrder(OrderRequest request) {
// 实际的订单处理逻辑
return new Order();
}
}
告警与通知机制
有了监控数据后,我们还需要设置合理的告警阈值:
@Component
public class QpsAlertService {
private final MeterRegistry meterRegistry;
private final int qpsThreshold = 1000; // 每秒1000次请求为阈值
public QpsAlertService(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@Scheduled(fixedRate = 5000) // 每5秒检查一次
public void checkQpsAlert() {
Double qps = getCurrentQps();
if (qps != null && qps > qpsThreshold) {
sendAlert("QPS过高", "当前QPS: " + qps + ", 阈值: " + qpsThreshold);
}
}
private Double getCurrentQps() {
// 获取当前QPS
return meterRegistry.find("http_requests_total").counter().count();
}
private void sendAlert(String title, String message) {
// 发送告警通知
// 可以集成钉钉、企业微信等
System.out.println("告警: " + title + " - " + message);
}
}
最佳实践与注意事项
- 选择合适的监控粒度:不要过度监控,只关注核心指标
- 设置合理的采样率:避免监控本身影响系统性能
- 建立多层次告警:设置不同的告警级别和阈值
- 定期清理历史数据:避免监控数据占用过多存储空间
- 监控监控系统本身:确保监控系统正常运行
总结
通过SpringBoot实现QPS监控,我们能够实时了解系统运行状态,及时发现性能瓶颈和异常情况。在实际应用中,建议结合Micrometer、Prometheus等成熟方案,同时根据业务特点定制化监控指标。
记住,监控不是可有可无的装饰品,而是保障系统稳定运行的重要基础设施。别等系统宕机了才知道加监控的重要性,从现在开始,为你的系统建立完善的监控体系吧!
标题:SpringBoot 实现QPS监控:别等系统宕机了才知道加监控
作者:jiangyi
地址:http://jiangyi.space/articles/2025/12/26/1766729054083.html
0 评论