当前位置: 首页 > news >正文

Spring Boot 监控:AOP vs Filter vs Java Agent

在这里插入图片描述

01前言

在 高并发 + 微服务 中,
传统 手动埋点(System.currentTimeMillis())就像用体温计量火箭速度——代码侵入、重复劳动、维护爆炸。
下文是无侵入、高精度、全链路 监控 API 耗时,全程不碰业务代码的方案!

02实战:6 种方案横向对比

在这里插入图片描述

03方案详解

方案 1:StopWatch(临时调试)
代码:

@GetMapping("/query")
public ResponseEntity<String> query() throws Exception {StopWatch stopWatch = new StopWatch(); // 创建计时器stopWatch.start(); // 开始计时TimeUnit.MILLISECONDS.sleep(new Random().nextLong(2000)); // 模拟业务stopWatch.stop(); // 结束计时System.out.printf("**方法耗时:%dms**%n", stopWatch.getTotalTimeMillis());return ResponseEntity.ok("api query...");
}

注解:

  1. StopWatch 是 Spring 提供的轻量级计时工具。
  2. 侵入性强:需手动插入到业务代码中。
  3. 适合 临时调试,生产环境 不推荐。

方案 2:AOP 切面(无侵入)
代码:

@Aspect // 声明切面
@Component
public class PerformanceAspect {private static final Logger logger = LoggerFactory.getLogger("api.timed");@Around("@annotation(org.springframework.web.bind.annotation.GetMapping)") // 拦截所有 Get 请求public Object recordExecutionTime(ProceedingJoinPoint pjp) throws Throwable {StopWatch sw = new StopWatch();sw.start();Object result = pjp.proceed(); // 执行原方法sw.stop();logger.info("**方法【{}】耗时: {}ms**", pjp.getSignature(), sw.getTotalTimeMillis());return result;}
}

注解:

  1. @Around 注解拦截所有 GetMapping 方法,零侵入。
  2. 通过 ProceedingJoinPoint 获取方法签名,精准定位慢接口。
  3. 缺点:无法监控非 Spring 管理的类(如手动 new 的对象)。

方案 3:拦截器(Controller 层统一监控)
代码:

public class TimedInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {request.setAttribute("startTime", System.currentTimeMillis()); // 记录开始时间return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {long startTime = (long) request.getAttribute("startTime");long cost = System.currentTimeMillis() - startTime;System.out.printf("**请求【%s】耗时: %dms**%n", request.getRequestURI(), cost);}
}@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new TimedInterceptor()).addPathPatterns("/api/**"); // 拦截所有 /api 下的请求}
}

注解:

  1. preHandle 在请求前记录时间,afterCompletion 在请求后计算耗时。
  2. 只适用于 Controller 层,无法监控 Service/DAO 层方法。
  3. 配置简单,适合 Web 项目快速接入。

方案 4:Filter(Servlet 级通用监控)
代码:

@Component
public class RequestTimingFilter implements Filter {private static final Logger logger = LoggerFactory.getLogger(RequestTimingFilter.class);@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request;long startTime = System.nanoTime(); // 高精度计时try {chain.doFilter(request, response); // 继续处理请求} finally {long duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);logger.info("**[{}] {} - {}ms (Status: {})**",httpRequest.getMethod(),httpRequest.getRequestURI(),duration,((HttpServletResponse) response).getStatus());}}
}

注解:

  1. 全局生效,所有请求(包括静态资源)都会被监控。
  2. 粒度较粗,无法定位具体方法耗时。
  3. 可通过 excludePaths 过滤不需要监控的 URI。

方案 5:事件监听(零侵入全局统计)
代码:

@Component
public class TimedListener {@EventListener(ServletRequestHandledEvent.class)public void recordTimed(ServletRequestHandledEvent event) {System.err.println("**请求监控事件: " + event + "**");}
}

注解:

  1. Spring 内部事件机制,无需任何配置。
  2. 只能获取 总耗时,无法拆分各阶段耗时。
  3. 适合 快速接入,不适合精细化监控。

方案 6:Micrometer + Prometheus(可视化监控)
代码:

@RestController
public class ApiController {@Timed(value = "api.query", description = "查询业务接口") // 关键注解@GetMapping("/query")public ResponseEntity<String> query() throws Exception {TimeUnit.MILLISECONDS.sleep(new Random().nextLong(2000));return ResponseEntity.ok("api query...");}
}

配置:

# application.yml
management:endpoints:web:exposure:include: prometheus # 暴露 Prometheus 端点metrics:export:prometheus:enabled: true
Prometheus 配置:- job_name: "spring-boot-app"metrics_path: "/actuator/prometheus"static_configs:- targets: ["localhost:8080"]

注解:

  1. @Timed 注解 零侵入,自动记录耗时指标。
  2. Prometheus + Grafana 可视化展示,支持 报警规则。
  3. 缺点:需引入额外依赖,适合生产环境。

方案 7:SkyWalking(分布式全链路追踪)
启动命令:

java -javaagent:/path/skywalking-agent.jar \-Dskywalking.agent.service_name=your-app \-jar your-app.jar

注解:

  1. 无代码侵入,通过 Java Agent 自动注入。
  2. 支持 分布式链路追踪,跨服务追踪耗时。
  3. 适合微服务架构,强烈推荐!

如何选?

• 单体应用:Micrometer + Prometheus(可视化 + 报警)。
• 微服务架构:SkyWalking(全链路追踪)。
• 临时调试:Arthas(在线诊断神器)。

http://www.dtcms.com/a/284591.html

相关文章:

  • BI 数据可视化平台建设(3)—首页性能提升实践
  • ThinkPHP8 Windows开发全流程:从搭建到上线
  • 【Android代码】绘本翻页时通过AI识别,自动通过手机/pad朗读绘本
  • MTK平台--如何查询手机连接的TX速率和带宽
  • Android本地浏览PDF(Android PDF.js 简要学习手册)
  • [MRCTF2020]PYWebsite
  • 大语言模型任务分解与汇总:从认知瓶颈到系统化解决方案
  • ubuntu基础搭建
  • 学习笔记(39):结合生活案例,介绍 10 种常见模型
  • Matplotlib 轴标题与刻度字号调整方法
  • 渗透总结一
  • docker中 contriner 和 images 什么关系
  • Oracle 成本优化器(CBO)与数据库统计信息:核心原理与实践
  • 深度学习计算图学习路线
  • Python获取网页乱码问题终极解决方案 | Python爬虫编码处理指南
  • UE5 lumen
  • 《Oracle SQL:使用 RTRIM 和 TO_CHAR 函数格式化数字并移除多余小数点》
  • 解读PLM系统软件在制造企业研发管理中的应用
  • 【神经网络在MATLAB中是如何实现的?】
  • 解锁Windows下Composer切换PHP版本的奥秘
  • 老牌支付品牌钱如潮入局本地生活抽佣系统,行业竞争加剧
  • Linux Shell脚本
  • linux端口监听命令
  • 支付宝智能助理用户会话实时统计:Flink定时器与状态管理实战解析
  • 全面升级!WizTelemetry 可观测平台 2.0 深度解析:打造云原生时代的智能可观测平台
  • cve-2012-0809 sudo格式化字符串漏洞分析及利用
  • TASK01【datawhale组队学习】地瓜机器人具身智能概述
  • Jmeter系列(八)-定时器(待更新)
  • 电缆安全双保险:不止防盗,更能防触电的塔能智慧照明守护方案
  • 【推荐100个unity插件】使用C#或者unity实现爬虫爬取静态网页数据——Html Agility Pack (HAP)库和XPath 语法的使用