亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot首筆交易慢問(wèn)題排查與優(yōu)化方案

 更新時(shí)間:2025年04月07日 15:19:13   作者:MrWho  
在我們的微服務(wù)項(xiàng)目中,遇到這樣的問(wèn)題:應(yīng)用啟動(dòng)后,第一筆交易響應(yīng)耗時(shí)高達(dá)4、5秒,而后續(xù)請(qǐng)求均能在毫秒級(jí)完成,這不僅觸發(fā)監(jiān)控告警,也極大影響了用戶體驗(yàn),本文將結(jié)合日志排查、性能工具分析以及預(yù)熱優(yōu)化手段,總結(jié)出一套完整的排查思路和解決方案

問(wèn)題背景

在我們的微服務(wù)系統(tǒng)中,首筆交易響應(yīng)明顯偏慢,經(jīng)過(guò)初步排查發(fā)現(xiàn):

  • Flowable 流程部署、Redis 連接建立、PageHelper 代理生成和 Hibernate Validator 校驗(yàn)等操作均集中在首筆交易時(shí)進(jìn)行;
  • 后續(xù)交易響應(yīng)迅速,說(shuō)明業(yè)務(wù)邏輯本身并無(wú)性能瓶頸,而主要問(wèn)題出在各類資源的首次初始化上。

這種“懶加載”機(jī)制雖然能夠延遲資源加載,但在首筆交易時(shí)往往會(huì)導(dǎo)致嚴(yán)重延時(shí),影響整體體驗(yàn)。實(shí)際項(xiàng)目中需平衡啟動(dòng)速度與首次響應(yīng)效率,主動(dòng)預(yù)熱關(guān)鍵組件。

排查步驟

1. 日志分析

首先,將日志級(jí)別調(diào)為 DEBUG,詳細(xì)觀察首筆交易與后續(xù)交易之間的差異。
在 Flowable 工作流啟動(dòng)時(shí),日志中會(huì)出現(xiàn)如下部署信息:

2025-03-31-15:24:25:326 [thread1] DEBUG o.f.e.i.bpmn.deployer.BpmnDeployer.deploy.72 -- Processing deployment SpringBootAutoDeployment
2025-03-31-15:24:25:340 [thread1] DEBUG o.f.e.i.b.d.ParsedDeploymentBuilder.build.54 -- Processing BPMN resource E:\gitProjects\flowableProject\target\classes\processes\eib.bpmn20.xml

同樣,Redis 連接在首次調(diào)用時(shí)會(huì)看到大量lettuce包日志,如:

2025-03-31-15:24:23:587 [XNIO-1 task-1] DEBUG io.lettuce.core.RedisClient.initializeChannelAsync0.304 -- Connecting to Redis at 10.240.75.250:7379

這些信息表明,在首次調(diào)用時(shí),系統(tǒng)才開(kāi)始部署流程、建立 Redis 連接以及加載其它第三方組件,從而導(dǎo)致延遲。

2. 性能工具定位

由于單純依賴日志排查比較繁瑣,我們還使用了 Java VisualVM(JDK 自帶工具,也可選擇其它工具)進(jìn)行采樣分析。
在 VisualVM 中選擇目標(biāo)進(jìn)程后通過(guò) CPU 取樣,示意圖如下(也可配置JMX遠(yuǎn)程連接)。

觀察結(jié)果如下:

發(fā)現(xiàn)首筆交易相比后續(xù)交易多出以下方法的調(diào)用(省略的部分二方包慢代碼):

  • com.github.pagehelper.dialect.auto.DataSourceAutoDialect.<init>
  • org.hibernate.validator.internal.engine.ValidatorImpl.validate()

這些方法的初始化也成為首筆交易慢的原因之一。

優(yōu)化方案:提前預(yù)熱各種資源

針對(duì)上述問(wèn)題,我們的優(yōu)化思路很簡(jiǎn)單:提前初始化各項(xiàng)資源,確保首筆交易時(shí)不再觸發(fā)大量懶加載。為此,我們將所有預(yù)熱操作改寫(xiě)成基于 ApplicationRunner 的實(shí)現(xiàn),保證在 Spring Boot 啟動(dòng)后就自動(dòng)執(zhí)行。

1. Flowable 流程部署預(yù)熱

在應(yīng)用啟動(dòng)時(shí),通過(guò)掃描 BPMN 文件提前部署流程,避免在交易中首次部署導(dǎo)致延遲。

import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.DeploymentBuilder;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;

@Component
public class ProcessDeploymentRunner implements ApplicationRunner {

    private final RepositoryService repositoryService;

    public ProcessDeploymentRunner(RepositoryService repositoryService) {
        this.repositoryService = repositoryService;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 掃描 processes 目錄下的所有 BPMN 文件
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("classpath:/processes/*.bpmn20.xml");

        if (resources.length == 0) {
            System.out.println("未在 processes 目錄下找到 BPMN 文件");
            return;
        }

        DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
                .name("自動(dòng)部署流程");

        for (Resource resource : resources) {
            deploymentBuilder.addInputStream(resource.getFilename(), resource.getInputStream());
        }

        deploymentBuilder.deploy();
        System.out.println("流程定義已部署,數(shù)量:" + resources.length);
    }
}

2. Redis 連接預(yù)熱

利用 ApplicationRunner 發(fā)送一次 PING 請(qǐng)求,提前建立 Redis 連接,避免首筆交易時(shí)因連接建立而耗時(shí)。

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class RedisWarmupRunner implements ApplicationRunner {

    private final StringRedisTemplate redisTemplate;

    public RedisWarmupRunner(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void run(ApplicationArguments args) {
        try {
            String pingResult = redisTemplate.getConnectionFactory().getConnection().ping();
            System.out.println("? Redis connection pre-warmed successfully: " + pingResult);
        } catch (Exception e) {
            System.err.println("? Redis warm-up failed: " + e.getMessage());
        }
    }
}

3. PageHelper 預(yù)熱

通過(guò)執(zhí)行一條簡(jiǎn)單的查詢語(yǔ)句,觸發(fā) PageHelper 及相關(guān) MyBatis Mapper 的初始化。

import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class PageHelperWarmupRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        try {
            boolean result = SqlRunner.db().selectObjs("SELECT 1").size() > 0;
            System.out.println("? PageHelper & SqlRunner pre-warm completed, result: " + result);
        } catch (Exception e) {
            System.err.println("? PageHelper pre-warm failed: " + e.getMessage());
        }
    }
}

(請(qǐng)確保配置文件中已開(kāi)啟 SQL Runner 功能:
mybatis-plus.global-config.enable-sql-runner=true

4. Hibernate Validator 預(yù)熱

通過(guò)一次 dummy 校驗(yàn)操作,提前加載 Hibernate Validator 相關(guān)類和反射邏輯

import jakarta.validation.Validation;
import jakarta.validation.Validator;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class ValidatorWarmupRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        try {
            Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
            DummyEntity dummy = new DummyEntity();
            validator.validate(dummy);
            System.out.println("? Hibernate Validator pre-warm completed!");
        } catch (Exception e) {
            System.err.println("? Hibernate Validator pre-warm failed: " + e.getMessage());
        }
    }

    private static class DummyEntity {
        @jakarta.validation.constraints.NotNull
        private String name;
    }
}

5. Undertow 預(yù)熱(可選)

如果使用 Undertow 作為內(nèi)嵌服務(wù)器,也可以通過(guò)主動(dòng)發(fā)送 HTTP 請(qǐng)求預(yù)熱相關(guān)資源。此外,在配置文件中開(kāi)啟過(guò)濾器提前初始化也有助于降低延遲。

在 application.yml 中設(shè)置:

server:
  undertow:
    eager-init-filters: true

再通過(guò)下面的代碼發(fā)送一次預(yù)熱請(qǐng)求:

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class UndertowWarmupRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        try {
            RestTemplate restTemplate = new RestTemplate();
            String response = restTemplate.getForObject("http://localhost:8080/health", String.class);
            System.out.println("? Undertow pre-warm completed, response: " + response);
        } catch (Exception e) {
            System.err.println("? Undertow pre-warm failed: " + e.getMessage());
        }
    }
}

總結(jié)

通過(guò)上述方案,我們將 Flowable 流程部署、Redis 連接、PageHelper 初始化、Hibernate Validator 校驗(yàn)和 Undertow 相關(guān)組件的預(yù)熱操作全部遷移到 ApplicationRunner 中,在應(yīng)用啟動(dòng)后就自動(dòng)執(zhí)行。這樣,首筆交易時(shí)不再需要進(jìn)行大量初始化工作,各項(xiàng)資源已預(yù)先加載,確保后續(xù)請(qǐng)求能達(dá)到毫秒級(jí)響應(yīng),大大提升了用戶體驗(yàn)并避免了無(wú)效的監(jiān)控告警。

以上就是SpringBoot首筆交易慢問(wèn)題排查與優(yōu)化方案的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot首筆交易慢問(wèn)題的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java使用PDFBox實(shí)現(xiàn)操作PDF文檔

    Java使用PDFBox實(shí)現(xiàn)操作PDF文檔

    這篇文章主要為大家詳細(xì)介紹了Java如何使用PDFBox實(shí)現(xiàn)操作PDF文檔,例如添加本地圖片、添加網(wǎng)絡(luò)圖片、圖片寬高自適應(yīng)、圖片水平垂直居中對(duì)齊等功能,需要的可以了解下
    2024-03-03
  • 淺談SpringBoot項(xiàng)目如何讓前端開(kāi)發(fā)提高效率(小技巧)

    淺談SpringBoot項(xiàng)目如何讓前端開(kāi)發(fā)提高效率(小技巧)

    這篇文章主要介紹了淺談SpringBoot項(xiàng)目如何讓前端開(kāi)發(fā)提高效率(小技巧),主要介紹了Swagger和Nginx提高效率的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • java書(shū)店系統(tǒng)畢業(yè)設(shè)計(jì) 用戶模塊(3)

    java書(shū)店系統(tǒng)畢業(yè)設(shè)計(jì) 用戶模塊(3)

    這篇文章主要介紹了java書(shū)店系統(tǒng)畢業(yè)設(shè)計(jì),第三步系統(tǒng)總體設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java編程求二叉樹(shù)的鏡像兩種方法介紹

    Java編程求二叉樹(shù)的鏡像兩種方法介紹

    這篇文章主要介紹了Java編程求二叉樹(shù)的鏡像兩種方法介紹,分享了兩種方法,遞歸與非遞歸,每種方法又分別介紹了兩種解決思路,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • mybatis不加@Parm注解報(bào)錯(cuò)的解決方案

    mybatis不加@Parm注解報(bào)錯(cuò)的解決方案

    這篇文章主要介紹了mybatis不加@Parm注解報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • springBoot動(dòng)態(tài)加載jar及如何將類注冊(cè)到IOC

    springBoot動(dòng)態(tài)加載jar及如何將類注冊(cè)到IOC

    在SpringBoot項(xiàng)目中動(dòng)態(tài)加載jar文件并將其類注冊(cè)到IOC容器是一種高級(jí)應(yīng)用方式,,這種方法為SpringBoot項(xiàng)目提供了更靈活的擴(kuò)展能力,使得項(xiàng)目可以在不修改原有代碼的基礎(chǔ)上增加新的功能模塊,感興趣的朋友一起看看吧
    2024-11-11
  • Spring實(shí)現(xiàn)資源的動(dòng)態(tài)加載和卸載的方法小結(jié)

    Spring實(shí)現(xiàn)資源的動(dòng)態(tài)加載和卸載的方法小結(jié)

    這篇文章主要介紹了Spring實(shí)現(xiàn)資源的動(dòng)態(tài)加載和卸載的方法小結(jié),文中通過(guò)代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-06-06
  • xxl-job對(duì)比ElasticJob使用示例詳解

    xxl-job對(duì)比ElasticJob使用示例詳解

    這篇文章主要為大家介紹了xxl-job對(duì)比ElasticJob使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Java中LinkedHashSet的實(shí)現(xiàn)原理詳解

    Java中LinkedHashSet的實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了Java中LinkedHasSet的實(shí)現(xiàn)原理詳解,LinkedHashSet?是具有可預(yù)知迭代順序的?Set?接口的哈希表和鏈接列表實(shí)現(xiàn),此實(shí)現(xiàn)與HashSet?的不同之處在于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表,需要的朋友可以參考下
    2023-09-09
  • IDEA一致卡在build時(shí)間過(guò)長(zhǎng)問(wèn)題解決

    IDEA一致卡在build時(shí)間過(guò)長(zhǎng)問(wèn)題解決

    有很多小伙伴在起項(xiàng)目的時(shí)候巨慢,特別影響開(kāi)發(fā)效率,本文主要介紹了IDEA一致卡在build時(shí)間過(guò)長(zhǎng)問(wèn)題解決,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06

最新評(píng)論