最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot中的7種耗時統(tǒng)計的實現(xiàn)方法與應用場景

 更新時間:2025年09月26日 08:37:01   作者:劉大華  
在日常開發(fā)中,經(jīng)常會遇到一些性能問題,這篇文章主要介紹了SpringBoot中的7種耗時統(tǒng)計的實現(xiàn)方法與應用場景,大家可以根據(jù)需要進行選擇

前言

在日常開發(fā)中,經(jīng)常會遇到一些性能問題。

比如用戶反饋:“這個頁面加載好慢??!” 這個時候,你該怎么辦?

首先就得找出到底是哪個方法、哪段代碼執(zhí)行時間過長。

只有找到了瓶頸,才能對癥下藥進行優(yōu)化。所以說,方法耗時統(tǒng)計是性能優(yōu)化中非常重要的一環(huán)。

接下來,我就給大家介紹七種實用的實現(xiàn)方式,從簡單到復雜,總有一種適合你!

1. System.currentTimeMillis()

這是最原始但最直接的方式,適用于快速驗證某段代碼的執(zhí)行時間。

public void doSomething() {
    long start = System.currentTimeMillis();

    // 模擬業(yè)務邏輯
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }

    long end = System.currentTimeMillis();
    System.out.println("方法執(zhí)行耗時:" + (end - start) + "ms");
}

優(yōu)點

  • 無需引入任何依賴
  • 簡單直觀,適合臨時調試

缺點

  • 代碼侵入性強
  • 多處使用時重復代碼多
  • 精度受系統(tǒng)時鐘影響(可能受NTP調整干擾)

適用場景

  • 本地開發(fā)調試
  • 快速驗證某段邏輯耗時

注意:該方法基于系統(tǒng)時間,不適用于高精度計時。推薦使用 System.nanoTime() 替代(見后文補充)。

2. 使用StopWatch工具類

Spring 提供了org.springframework.util.StopWatch類,支持分段計時和格式化輸出,適合需要統(tǒng)計多個子任務耗時的場景。

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());
}

輸出示例:

StopWatch '用戶處理流程': running time = 130897800 ns
-----------------------------------------
ms     %     Task name
-----------------------------------------
 50.00  38%  查詢用戶
 80.00  62%  更新緩存

優(yōu)點

  • 支持多任務分段計時
  • 輸出美觀,便于分析
  • 可命名任務,提升可讀性

缺點

  • 仍需手動插入代碼
  • 不適用于自動化監(jiān)控

適用場景

需要分析多個步驟耗時占比的復雜流程

3. 使用AOP切面+自定義注解(推薦)

通過面向切面編程(AOP),可以實現(xiàn)對指定方法的無侵入式耗時監(jiān)控。

第一步:定義注解

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

第二步:編寫切面

@Aspect
@Component
@Slf4j
@Order(1) // 確保優(yōu)先級
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);

            // 根據(jù)閾值決定日志級別
            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。

第三步:使用注解

@Service
public class UserService {

    @LogCostTime(value = "根據(jù)ID查詢用戶", threshold = 50)
    public User getUserById(Long id) {
        try {
            Thread.sleep(100); // 模擬耗時
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return userRepository.findById(id);
    }
}

輸出:

WARN  ... 方法: UserService.getUserById(根據(jù)ID查詢用戶) 耗時超閾值: 102 ms (閾值: 50 ms)

優(yōu)點

  • 低侵入:只需添加注解
  • 可復用:一處定義,多處使用
  • 可擴展:支持閾值告警、慢查詢監(jiān)控等

適用場景

  • 核心服務方法
  • 遠程調用(RPC/HTTP)
  • 數(shù)據(jù)庫查詢
  • 復雜計算邏輯

4. 使用Micrometer@Timed注解

Micrometer是現(xiàn)代Java應用的事實標準指標收集庫,與Spring Boot Actuator深度集成,支持對接 Prometheus、Grafana、Datadog 等監(jiān)控系統(tǒng)。

添加依賴

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

啟用指標端點

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

使用@Timed注解

@Service
public class BusinessService {

    @Timed(
        value = "business.process.time",
        description = "業(yè)務處理耗時",
        percentiles = {0.5, 0.95, 0.99}
    )
    public void process() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

訪問 /actuator/prometheus 可看到:

# 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

優(yōu)點

  • 標準化指標,支持多維度聚合
  • 可視化展示(Grafana)
  • 支持報警(Prometheus Alertmanager)

適用場景

  • 生產(chǎn)環(huán)境性能監(jiān)控
  • 微服務架構下的統(tǒng)一指標體系

5. 使用Java8的Instant與Duration

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

public void doSomething() {
    Instant start = Instant.now();

    // 業(yè)務邏輯
    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());
}

優(yōu)點

  • 使用現(xiàn)代時間 API,語義清晰
  • 線程安全,避免舊 Date 的坑

缺點

  • 仍需手動編碼
  • 性能略低于 nanoTime

適用場景

偏好 Java 8+ 新特性的項目

6. 異步方法耗時統(tǒng)計CompletableFuture

對于異步任務,可通過回調機制統(tǒng)計耗時。

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);
    });
}

優(yōu)點

  • 適用于非阻塞場景
  • 可結合線程池監(jiān)控

適用場景

  • 異步消息處理
  • 批量任務調度

7. 使用HandlerInterceptor統(tǒng)計 Web 請求耗時

在 Web 層通過攔截器統(tǒng)一記錄所有 Controller 請求的處理時間。

@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);
        }
    }
}

注冊攔截器:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private RequestTimeInterceptor requestTimeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(requestTimeInterceptor);
    }
}

輸出:

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

優(yōu)點

  • 全局覆蓋所有請求
  • 無需修改業(yè)務代碼

適用場景

  • Web 應用整體性能監(jiān)控
  • API 網(wǎng)關層耗時分析

總結

方案侵入性適用場景是否推薦
System.currentTimeMillis()臨時調試?? 僅調試
StopWatch分段計時分析?
AOP + 自定義注解核心方法監(jiān)控??? 強烈推薦
Micrometer @Timed生產(chǎn)監(jiān)控集成??? 生產(chǎn)首選
Instant + Duration現(xiàn)代化時間處理?
CompletableFuture 回調異步任務?
HandlerInterceptorWeb 請求全局監(jiān)控??

到此這篇關于SpringBoot中的7種耗時統(tǒng)計的實現(xiàn)方法與應用場景的文章就介紹到這了,更多相關SpringBoot統(tǒng)計耗時內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java 如何判斷是否是26個英文字母

    java 如何判斷是否是26個英文字母

    這篇文章主要介紹了java 如何判斷是否是26個英文字母的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • 解決java.util.RandomAccessSubList cannot be cast to java.util.ArrayList錯誤的問題

    解決java.util.RandomAccessSubList cannot be cas

    當你嘗試將RandomAccessSubList強制轉換為ArrayList時,會拋出ClassCastException異常,解決這個問題,你可以使用List接口進行操作,或者使用ArrayList的構造函數(shù)創(chuàng)建新的ArrayList對象來處理子列表
    2025-11-11
  • RabbitMq報錯reply-code=406 reply-text=PRECONDITION_FAILED解決

    RabbitMq報錯reply-code=406 reply-text=PRECONDITION_FAILED

    這篇文章主要為大家介紹了RabbitMq報錯reply-code=406 reply-text=PRECONDITION_FAILED分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Http服務與Dubbo服務相互轉換的SpringBoot代理節(jié)點實現(xiàn)方式

    Http服務與Dubbo服務相互轉換的SpringBoot代理節(jié)點實現(xiàn)方式

    文章主要討論如何在項目中增加一個SpringBoot節(jié)點,作為HTTP與Dubbo服務之間的代理節(jié)點,該節(jié)點通過注冊到Eureka,提供SpringCloud服務,并支持Dubbo代理Bean的管理,文章提到使用io.dubbo:spring-boot-starter-dubbo依賴,但遇到消費者配置生產(chǎn)者的問題
    2025-10-10
  • Java中的ArrayList和contains函數(shù)和擴容機制(源碼詳解)

    Java中的ArrayList和contains函數(shù)和擴容機制(源碼詳解)

    這篇文章主要介紹了Java中的ArrayList和contains函數(shù)和擴容機制,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-10-10
  • Java調用Pytorch模型實現(xiàn)圖像識別

    Java調用Pytorch模型實現(xiàn)圖像識別

    這篇文章主要為大家詳細介紹了Java如何調用Pytorch實現(xiàn)圖像識別功能,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以了解一下
    2023-06-06
  • Java全能工具類之Hutool的用法詳解

    Java全能工具類之Hutool的用法詳解

    Hutool是一個Java工具類庫,由國內(nèi)的程序員loolly開發(fā),目的是提供一些方便、快捷、實用的工具類和工具方法,本文就來詳細聊聊它的使用吧
    2023-03-03
  • java跳出多重循環(huán)的三種實現(xiàn)方式

    java跳出多重循環(huán)的三種實現(xiàn)方式

    文章主要介紹了Java中跳出多重循環(huán)的三種方式:使用`break`配合標簽、在布爾表達式中添加判斷變量、以及使用`try-catch`制造異常,每種方式都有具體的代碼示例,并輸出了相應的執(zhí)行結果
    2025-01-01
  • JVM執(zhí)行引擎的項目實踐

    JVM執(zhí)行引擎的項目實踐

    執(zhí)行引擎是Java虛擬機核心的組成部分之一,本文主要介紹了JVM執(zhí)行引擎的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-04-04
  • SpringBoot集成Kafka的步驟

    SpringBoot集成Kafka的步驟

    這篇文章主要介紹了SpringBoot集成Kafka的步驟,幫助大家更好的理解和使用SpringBoot,感興趣的朋友可以了解下
    2021-01-01

最新評論

邵阳县| 漳州市| 大荔县| 孟州市| 许昌县| 上犹县| 上虞市| 玉溪市| 尖扎县| 长武县| 双峰县| 化州市| 连江县| 包头市| 广南县| 浦县| 班戈县| 沙田区| 海伦市| 奇台县| 聂拉木县| 湟源县| 乃东县| 乌什县| 上林县| 平罗县| 襄城县| 乌兰县| 蒲城县| 鹿泉市| 弋阳县| 宜兴市| 奉新县| 盐边县| 普定县| 双桥区| 汝南县| 璧山县| 杭锦后旗| 孟村| 德江县|