一、SpringBoot监控核心基础方案
本次对话梳理了企业级SpringBoot监控三层体系,适配单体、集群、生产高并发场景:
-
基础能力:Spring Boot Actuator 提供健康、指标、线程、环境等监控端点,支持自定义业务监控。
-
可视化单机:Spring Boot Admin 提供UI面板、服务上下线告警、在线排查。
-
生产集群:Actuator + Prometheus + Grafana 标准架构,实现指标持久化、大盘可视化、阈值告警。
二、监控导致性能下降的核心原因(精准、不抽象)
线上监控卡顿、CPU高、GC频繁、Dubbo RT抖动,全部来自以下8个真实问题:
-
开启全部端点 *:每次采集都会扫描Bean、配置、类映射,CPU持续损耗。
-
健康检查串行+全量详情:DB/Redis/注册中心校验串行,慢依赖拖慢整个健康接口。
-
指标Tag高基数爆炸:URI、订单ID、用户ID当Tag,Meter无限膨胀,内存和FullGC暴涨。
-
Prometheus采集频率过高:1s/5s高频拉取prometheus端点,大量字符串序列化消耗CPU。
-
频繁dump线程/堆:threaddump遍历所有线程栈、heapdump触发STW,直接卡顿业务。
-
监控与业务共用线程池:监控慢、采集大,抢占Tomcat/容器线程,业务排队。
-
Admin心跳过密:10s一次上报元数据,集群量大时序列化+网络IO堆积。
-
自定义埋点不规范:接口内new Counter/Timer、埋点带IO查询,放大损耗。
-
【隐藏重点】指标抓取线程频繁遍历 Meter :SpringBoot Micrometer 每次Prometheus抓取,会遍历全部注册的Meter指标、反射取值、拼接文本。Dubbo高QPS服务指标量大、抓取频繁时,抓取线程CPU极高、抢占业务CPU,导致Dubbo RT周期性抖动、CPU毛刺。
三、纯Dubbo服务专属性能问题(无HTTP接口场景)
Dubbo服务最容易被忽略的隐形性能开销:
-
不关闭Web容器:没任何HTTP业务,却常驻Tomcat线程、加载Web Bean、生成无效HTTP指标。
-
监控复用业务线程:Actuator占用容器线程池,高QPS Dubbo调用出现线程抢占、RT抖动。
-
默认无Dubbo指标:只监控HTTP,RPC调用量、耗时、异常完全黑盒。
-
保留多余端点:beans、env、configprops 持续扫描容器,空耗CPU。
四、生产可直接上线完整配置(Dubbo服务、无HTTP)
适用场景:纯Dubbo提供者、没有Controller、不对外HTTP业务、需要Prometheus监控、性能最优。
核心策略:关闭Web > 独立监控端口 > 最小端点暴露 > 关闭无效指标 > 并行健康检查
yaml
# 1. 彻底关闭Web容器(最关键性能优化)
spring:
main:
web-application-type: none
# 2. Dubbo基础配置(不影响原有业务)
dubbo:
application:
name: dubbo-provider-service
metrics:
protocol: prometheus
enable-jvm-metrics: true # 开启Dubbo官方RPC指标
# 3. Actuator性能最优配置(生产稳定版)
management:
# 监控端口独立隔离,不和Dubbo/业务抢占线程
server:
port: 8090
address: 127.0.0.1 # 只允许本机/内网Prometheus抓取,禁止外网
# 只开放【生产必需】端点,杜绝扫描型端点
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
# 健康检查优化:并行+不泄露敏感详情
endpoint:
health:
show-details: on-authorized
parallel:
enabled: true # 并行检查DB/Redis/Nacos,消除串行阻塞
probes:
enabled: true # 兼容k8s存活/就绪探针
# 关闭所有无效Web指标,彻底瘦身Meter数量
metrics:
web:
server:
requests:
autotime:
enabled: false
client:
requests:
autotime:
enabled: false
http:
server:
enabled: false
# 自定义服务信息(轻量、无开销)
info:
app:
name: dubbo-provider-service
version: 1.0.0
五、关键配置逐行性能解释
-
web-application-type: none:不启动Tomcat,无Web线程池、无Http对象GC,节省内存+CPU。 -
management.port=8090 + 127.0.0.1:监控单独线程池,完全不影响Dubbo Netty线程,安全且隔离。 -
include: health,info,metrics,prometheus:彻底关闭 beans、env、configprops、mappings 等耗CPU端点,大幅减少抓取时Meter遍历数量。 -
health.parallel=true:多个健康检查并行执行,避免单个慢依赖拖垮整体健康接口。 -
web.requests.autotime=false:禁用无效HTTP指标采集,防止Meter爆炸、内存泄漏,从根源减少抓取线程遍历开销。
六、Dubbo接口监控埋点可直接使用代码(无性能损耗)
替代HTTP监控,实现Dubbo调用量、耗时、超时、异常监控,纯内存原子操作、无IO、不影响性能。
java
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.springframework.stereotype.Component;
@Component
@Activate(group = {CommonConstants.PROVIDER})
public class DubboMetricsFilter implements Filter {
private final Timer.Builder dubboTimerBuilder;
// 构造器初始化,不在请求内创建对象
public DubboMetricsFilter(MeterRegistry registry) {
this.dubboTimerBuilder = Timer.builder("dubbo.provider.request")
.description("dubbo接口调用耗时");
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String status = "success";
long start = System.currentTimeMillis();
try {
return invoker.invoke(invocation);
} catch (RpcException e) {
status = e.isTimeout() ? "timeout" : "rpc_ex";
throw e;
} catch (Exception e) {
status = "biz_ex";
throw e;
} finally {
// 固定tag,无高基数,绝对不内存爆炸
dubboTimerBuilder
.tag("interface", invoker.getInterface().getSimpleName())
.tag("method", invocation.getMethodName())
.tag("status", status)
.register(invoker.getRegistry())
.record(System.currentTimeMillis() - start, java.util.concurrent.TimeUnit.MILLISECONDS);
}
}
}
七、Prometheus采集配置(生产标准)
杜绝高频采集导致CPU高,统一规范采集周期。
yaml
scrape_configs:
- job_name: 'dubbo-service'
metrics_path: '/actuator/prometheus'
scrape_interval: 15s # 生产固定15s,禁止1s/5s
static_configs:
- targets: ['127.0.0.1:8090']
八、最终上线性能收益(量化)
-
彻底消除Tomcat空转,常驻内存下降10%~20%。
-
删除成千上万个无效HTTP Meter,杜绝长期GC压力。
-
监控线程与Dubbo业务线程完全隔离,RPC RT不再抖动。
-
端点最小化暴露,监控CPU损耗从10%+降至 <1%。
-
Dubbo全量接口可观测,无埋点性能副作用。
九、生产禁止操作(避坑重点)
-
禁止
include: *全量端点。 -
禁止Prometheus采集间隔小于15s,减少抓取线程执行频次。
-
禁止将订单ID、用户ID、动态参数作为metrics tag。
-
禁止定时/脚本频繁调用 threaddump、heapdump。
-
禁止Dubbo Filter内写日志、DB、HTTP调用、复杂计算。
-
禁止保留无用自动指标,避免抓取线程每次遍历数万无效Meter。