SpringBoot 中的 7 种耗时统计方式,你用过几种?

前言

在日常开发中,经常会遇到一些性能问题。

比如用户反馈:“这个页面加载好慢啊!” 这个时候,你该怎么办?

首先就得找出到底是哪个方法、哪段代码执行时间过长。

只有找到了瓶颈,才能对症下药进行优化。所以说,方法耗时统计是性能优化中非常重要的一环。

接下来,我就给大家介绍七种实用的实现方式,从简单到复杂,总有一种适合你!


1. System.currentTimeMillis()

这是最原始但最直接的方式,适用于快速验证某段代码的执行时间。

java

体验AI代码助手

代码解读

复制代码

public void doSomething() { long start = System.currentTimeMillis(); // 模拟业务逻辑 try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } long end = System.currentTimeMillis(); System.out.println("方法执行耗时:" + (end - start) + "ms"); }

优点
  • 无需引入任何依赖
  • 简单直观,适合临时调试
缺点
  • 代码侵入性强
  • 多处使用时重复代码多
  • 精度受系统时钟影响(可能受NTP调整干扰)
适用场景
  • 本地开发调试
  • 快速验证某段逻辑耗时

⚠️ 注意:该方法基于系统时间,不适用于高精度计时。推荐使用System.nanoTime()替代(见后文补充)。


2. 使用StopWatch工具类

Spring 提供了org.springframework.util.StopWatch类,支持分段计时和格式化输出,适合需要统计多个子任务耗时的场景。

java

体验AI代码助手

代码解读

复制代码

import org.springframework.util.StopWatch; public void processUserFlow() { StopWatch stopWatch = new StopWatch("用户处理流程"); stopWatch.start("查询用户"); // 查询逻辑... Thread.sleep(50); stopWatch.stop(); stopWatch.start("更新缓存"); // 缓存操作... Thread.sleep(80); stopWatch.stop(); log.info(stopWatch.prettyPrint()); }

输出示例:

markdown

体验AI代码助手

代码解读

复制代码

StopWatch '用户处理流程': running time = 130897800 ns ----------------------------------------- ms % Task name ----------------------------------------- 50.00 38% 查询用户 80.00 62% 更新缓存

优点
  • 支持多任务分段计时
  • 输出美观,便于分析
  • 可命名任务,提升可读性
缺点
  • 仍需手动插入代码
  • 不适用于自动化监控
适用场景
  • 需要分析多个步骤耗时占比的复杂流程

3. 使用AOP切面+自定义注解(推荐)

通过面向切面编程(AOP),可以实现对指定方法的无侵入式耗时监控。

第一步:定义注解

java

体验AI代码助手

代码解读

复制代码

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogCostTime { String value() default ""; // 方法描述 long threshold() default 0; // 耗时阈值(ms),超过则告警 }

第二步:编写切面

java

体验AI代码助手

代码解读

复制代码

@Aspect @Component @Slf4j @Order(1) // 确保优先级 public class CostTimeAspect { @Around("@annotation(logCostTime)") public Object around(ProceedingJoinPoint pjp, LogCostTime logCostTime) throws Throwable { String methodName = pjp.getSignature().getName(); String desc = logCostTime.value(); long threshold = logCostTime.threshold(); long start = System.nanoTime(); // 高精度计时 Object result; try { result = pjp.proceed(); } finally { long costNanos = System.nanoTime() - start; long costMillis = TimeUnit.NANOSECONDS.toMillis(costNanos); // 根据阈值决定日志级别 if (threshold > 0 && costMillis > threshold) { log.warn("方法: {}.{}({}) 耗时超阈值: {} ms (阈值: {} ms)", pjp.getTarget().getClass().getSimpleName(), methodName, desc, costMillis, threshold); } else { log.info("方法: {}.{}({}) 耗时: {} ms", pjp.getTarget().getClass().getSimpleName(), methodName, desc, costMillis); } } return result; } }

注意:需确保项目已启用 AOP,Spring Boot 默认支持;否则需添加@EnableAspectJAutoProxy

第三步:使用注解

java

体验AI代码助手

代码解读

复制代码

@Service public class UserService { @LogCostTime(value = "根据ID查询用户", threshold = 50) public User getUserById(Long id) { try { Thread.sleep(100); // 模拟耗时 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return userRepository.findById(id); } }

输出:

css

体验AI代码助手

代码解读

复制代码

WARN ... 方法: UserService.getUserById(根据ID查询用户) 耗时超阈值: 102 ms (阈值: 50 ms)

优点
  • 低侵入:只需添加注解
  • 可复用:一处定义,多处使用
  • 可扩展:支持阈值告警、慢查询监控等
适用场景
  • 核心服务方法
  • 远程调用(RPC/HTTP)
  • 数据库查询
  • 复杂计算逻辑

4. 使用Micrometer@Timed注解

Micrometer是现代Java应用的事实标准指标收集库,与Spring Boot Actuator深度集成,支持对接 Prometheus、Grafana、Datadog 等监控系统。

添加依赖

xml

体验AI代码助手

代码解读

复制代码

<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-core</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

启用指标端点

yaml

体验AI代码助手

代码解读

复制代码

management: endpoints: web: exposure: include: metrics, prometheus metrics: export: prometheus: enabled: true

使用@Timed注解

java

体验AI代码助手

代码解读

复制代码

@Service public class BusinessService { @Timed( value = "business.process.time", description = "业务处理耗时", percentiles = {0.5, 0.95, 0.99} ) public void process() { try { Thread.sleep(200); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }

访问/actuator/prometheus可看到:

ini

体验AI代码助手

代码解读

复制代码

# HELP business_process_time_seconds # TYPE business_process_time_seconds summary business_process_time_seconds_count{method="process",} 1.0 business_process_time_seconds_sum{method="process",} 0.201

优点
  • 标准化指标,支持多维度聚合
  • 可视化展示(Grafana)
  • 支持报警(Prometheus Alertmanager)
适用场景
  • 生产环境性能监控
  • 微服务架构下的统一指标体系

5. 使用Java8的InstantDuration

Java 8 引入了新的时间 API,更加安全和易用。

java

体验AI代码助手

代码解读

复制代码

public void doSomething() { Instant start = Instant.now(); // 业务逻辑 try { Thread.sleep(150); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } Instant end = Instant.now(); Duration duration = Duration.between(start, end); log.info("耗时:{} ms", duration.toMillis()); }

优点
  • 使用现代时间 API,语义清晰
  • 线程安全,避免旧 Date 的坑
缺点
  • 仍需手动编码
  • 性能略低于nanoTime
适用场景
  • 偏好 Java 8+ 新特性的项目

6. 异步方法耗时统计CompletableFuture

对于异步任务,可通过回调机制统计耗时。

java

体验AI代码助手

代码解读

复制代码

public CompletableFuture<Void> asyncProcess() { long start = System.nanoTime(); return CompletableFuture.runAsync(() -> { // 模拟异步任务 try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).whenComplete((result, ex) -> { long cost = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start); log.info("异步任务耗时:{} ms", cost); }); }

优点
  • 适用于非阻塞场景
  • 可结合线程池监控
适用场景
  • 异步消息处理
  • 批量任务调度

7. 使用HandlerInterceptor统计 Web 请求耗时

在 Web 层通过拦截器统一记录所有 Controller 请求的处理时间。

java

体验AI代码助手

代码解读

复制代码

@Component public class RequestTimeInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { request.setAttribute("startTime", System.nanoTime()); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { Long start = (Long) request.getAttribute("startTime"); if (start != null) { long costNanos = System.nanoTime() - start; long costMillis = TimeUnit.NANOSECONDS.toMillis(costNanos); String uri = request.getRequestURI(); log.info("HTTP {} {} 耗时: {} ms", request.getMethod(), uri, costMillis); } } }

注册拦截器:

java

体验AI代码助手

代码解读

复制代码

@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private RequestTimeInterceptor requestTimeInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(requestTimeInterceptor); } }

输出:

sql

体验AI代码助手

代码解读

复制代码

HTTP GET /api/user/123 耗时: 105 ms

优点
  • 全局覆盖所有请求
  • 无需修改业务代码
适用场景
  • Web 应用整体性能监控
  • API 网关层耗时分析

总结

方案侵入性适用场景是否推荐
System.currentTimeMillis()临时调试⚠️ 仅调试
StopWatch分段计时分析
AOP + 自定义注解核心方法监控✅✅✅ 强烈推荐
Micrometer@Timed生产监控集成✅✅✅ 生产首选
Instant + Duration现代化时间处理
CompletableFuture回调异步任务
HandlerInterceptorWeb 请求全局监控✅✅

希望这篇文章对你有帮助!如果你有更好的方法,欢迎在评论区分享~ 若有不对的地方也欢迎提出指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1134986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模型诊所:使用Llama Factory诊断和修复问题模型

模型诊所&#xff1a;使用Llama Factory诊断和修复问题模型 作为一名AI工程师&#xff0c;你是否遇到过这样的困境&#xff1a;精心准备的数据集、调了无数次的参数&#xff0c;但模型微调效果依然不尽如人意&#xff1f;这时候&#xff0c;一个专业的诊断工具就显得尤为重要。…

基于python的婚纱影楼服务平台设计和实现_0uwse39z

目录婚纱影楼服务平台设计与实现核心功能模块技术实现特点安全与扩展性关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;婚纱影楼服务平台设计与实现 该平台基于Python技术栈开发&am…

语音合成环境总冲突?这个镜像已修复numpy/scipy版本问题

语音合成环境总冲突&#xff1f;这个镜像已修复numpy/scipy版本问题 &#x1f4d6; 项目简介 在语音合成&#xff08;Text-to-Speech, TTS&#xff09;的实际部署中&#xff0c;开发者常常面临一个令人头疼的问题&#xff1a;依赖包版本冲突。尤其是在使用基于 Hugging Face da…

CRNN OCR与智能客服结合:图片咨询自动回复

CRNN OCR与智能客服结合&#xff1a;图片咨询自动回复 &#x1f4d6; 项目简介 在现代智能客服系统中&#xff0c;用户通过上传截图、发票、手写便条等方式进行图文咨询的场景日益普遍。传统的文本输入识别已无法满足多模态交互需求&#xff0c;OCR&#xff08;光学字符识别&am…

用Apache Atlas快速构建数据目录原型的方法

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个快速原型生成器&#xff1a;1. 根据用户输入的业务领域自动生成Atlas类型定义 2. 创建示例数据实体 3. 生成基础UI展示数据目录 4. 导出可部署的包。使用DeepSeek模型理解…

国家电网Java面试被问:最小生成树的Kruskal和Prim算法

一、基础概念 1.1 最小生成树定义 最小生成树&#xff08;Minimum Spanning Tree, MST&#xff09;&#xff1a;在带权连通无向图中&#xff0c;找到一个边的子集&#xff0c;使得&#xff1a; 包含所有顶点 没有环 边的总权重最小 1.2 应用场景 网络设计&#xff1a;以最…

CRNN OCR与LangChain集成:快速构建文档智能处理流水线

CRNN OCR与LangChain集成&#xff1a;快速构建文档智能处理流水线 &#x1f4d6; 项目简介 在数字化转型加速的今天&#xff0c;文档智能处理已成为企业自动化流程中的关键环节。从发票识别、合同解析到证件信息提取&#xff0c;OCR&#xff08;光学字符识别&#xff09;技术…

Llama Factory性能优化:让你的微调速度提升300%的秘籍

Llama Factory性能优化&#xff1a;让你的微调速度提升300%的秘籍 作为一名长期与大型语言模型打交道的工程师&#xff0c;我深刻理解模型微调过程中的痛点——尤其是当看到训练进度条像蜗牛一样缓慢移动时。最近通过系统实践Llama Factory的各项优化技巧&#xff0c;成功将单次…

24小时开发实战:快速构建图片解密APP原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 使用快马平台快速开发一个图片解密APP原型&#xff0c;要求&#xff1a;1. 响应式网页界面&#xff1b;2. 图片上传和预览功能&#xff1b;3. 集成开源的steg库进行解密&#xff1…

企业级系统SSL证书路径问题实战解决方案

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个企业SSL证书管理模拟器&#xff0c;模拟以下场景&#xff1a;1) 多层级CA证书链 2) 混合环境(Java/.NET) 3) 证书自动更新机制。要求&#xff1a;使用DeepSeek模型生成诊断…

基于python的家庭成员亲子相册图片照片管理系统的设计与实现_192n2568

目录系统设计目标技术架构核心功能模块创新点应用价值关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;系统设计目标 该系统旨在通过Python技术构建一个高效、易用的家庭成员亲子相册…

Kimi类应用核心技术复现:多情感语音合成完整流程

Kimi类应用核心技术复现&#xff1a;多情感语音合成完整流程 &#x1f4cc; 技术背景与核心价值 随着AI语音助手、虚拟主播、有声阅读等应用场景的爆发式增长&#xff0c;传统“机械朗读”式的语音合成已无法满足用户对自然度和表现力的需求。多情感语音合成&#xff08;Emot…

AI配音成本大缩水:Sambert-Hifigan镜像部署,替代商业TTS方案

AI配音成本大缩水&#xff1a;Sambert-Hifigan镜像部署&#xff0c;替代商业TTS方案 一、中文多情感语音合成的技术演进与成本挑战 在智能客服、有声书生成、短视频配音等应用场景中&#xff0c;高质量的中文多情感语音合成&#xff08;Text-to-Speech, TTS&#xff09; 正变…

中文多情感语音合成新选择:Sambert-HifiGan全面解析

中文多情感语音合成新选择&#xff1a;Sambert-HifiGan全面解析 一、引言&#xff1a;中文多情感语音合成的技术演进与现实需求 随着智能语音助手、有声读物、虚拟主播等应用的普及&#xff0c;传统“机械式”语音合成已无法满足用户对自然度和表现力的需求。尤其在中文场景下…

如何用AI自动解决Python请求重试错误

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个Python脚本&#xff0c;使用requests库实现智能重试机制&#xff0c;当遇到网络请求失败时自动重试。要求&#xff1a;1) 支持自定义重试次数和间隔时间 2) 能识别不同类型…

Sambert-HifiGan在虚拟主播中的应用:打造逼真数字人

Sambert-HifiGan在虚拟主播中的应用&#xff1a;打造逼真数字人 引言&#xff1a;语音合成如何赋能虚拟主播&#xff1f; 随着AIGC技术的快速发展&#xff0c;虚拟主播正从“动起来”迈向“说得好”的新阶段。早期的数字人多依赖预录语音或机械式TTS&#xff08;文本转语音&a…

5分钟用VUE UI组件库打造产品原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 使用快马平台&#xff0c;输入以下提示词生成一个快速原型的VUE UI组件库项目&#xff1a;生成一个用于快速原型的VUE UI组件库&#xff0c;支持拖拽式界面设计。包含常见的登录页…

智能家居中PCTOLCD2002的实战开发指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个智能温控器的LCD显示项目&#xff0c;使用PCTOLCD2002驱动芯片。需要实现&#xff1a;1) 温度数字显示 2) 湿度百分比显示 3) 模式图标(制冷/制热/自动) 4) 设置菜单界面 …

TCL华星光电对Prima的收购进一步对终端市场的把控

品牌与面板厂深化垂直整合&#xff0c;TCL华星收购案是大趋势缩影集邦咨询&#xff08;TrendForce&#xff09;指出&#xff1a;品牌与面板制造商进军 micro/miniLED 领域&#xff0c;垂直整合趋势深化。中国家电巨头 TCL科技 近日宣布&#xff0c;其子公司 TCL华星&#xff08…

Llama Factory魔法书:从零开始构建智能问答系统

Llama Factory魔法书&#xff1a;从零开始构建智能问答系统 为什么选择 Llama Factory&#xff1f; 如果你正在为初创公司开发行业专用的问答系统&#xff0c;却苦于没有足够的预算雇佣AI专家&#xff0c;那么 Llama Factory 就是你的救星。这个开源框架整合了主流的高效训练微…