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

SpringBoot基于線程池的訂單創(chuàng)建并行化實踐過程

 更新時間:2025年12月26日 08:52:13   作者:kkkkkkkkl24  
文章介紹了電商系統(tǒng)訂單創(chuàng)建接口的并行處理方案,通過分析業(yè)務流程、選擇合適的線程池和技術,解決了高并發(fā)場景下的性能問題

一、背景

1.1 業(yè)務背景

以電商系統(tǒng)「訂單創(chuàng)建」接口為例

一個用戶下單請求,往往需要完成多個業(yè)務步驟:

  • 校驗庫存
  • 校驗用戶信息
  • 計算訂單價格
  • 鎖庫存
  • 創(chuàng)建訂單

1.2 問題描述

傳統(tǒng)實現(xiàn)方式:串行執(zhí)行

在高并發(fā)場景下:

  • 接口 RT 高
  • 線程被長時間占用
  • 系統(tǒng)吞吐下降

1.3 技術挑戰(zhàn)

  • 哪些任務可以并行?
  • 如何安全、高效地并行?
  • 如何在 Spring Boot 中正確使用線程池?

二、業(yè)務場景分析與并行拆分

2.1 訂單創(chuàng)建流程拆解

步驟是否存在依賴是否可并行
校驗庫存?
校驗用戶?
計算價格?
鎖庫存依賴庫存校驗?
創(chuàng)建訂單依賴前置結果?

2.2 并行化設計思路

  • 無依賴的校驗類任務 → 并行
  • 存在業(yè)務依賴的核心流程 → 串行
  • 線程池只用于短生命周期任務

三、技術選型與整體設計

3.1 為什么不直接 new Thread?

  • 線程創(chuàng)建成本高
  • 無法控制并發(fā)量
  • 高并發(fā)下容易導致 JVM 失控

3.2 為什么選擇線程池 + CompletableFuture?

  • 線程復用,降低系統(tǒng)開銷
  • 明確的并發(fā)上限
  • 支持任務編排(allOf / thenCombine)

3.3 在 Spring Boot 中的正確姿勢

  • 線程池必須交由 Spring 管理
  • 使用 ThreadPoolTaskExecutor
  • 為業(yè)務定制專用線程池,避免互相影響

四、線程池設計與配置(Core)

4.1 線程池配置代碼

@Configuration
public class OrderThreadPoolConfig {

    @Bean("orderExecutor")
    public ThreadPoolTaskExecutor orderExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(8);
        executor.setMaxPoolSize(16);
        executor.setQueueCapacity(200);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("order-create-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

4.2 關鍵參數(shù)說明

  • corePoolSize:常態(tài)并發(fā)能力
  • maxPoolSize:應對突發(fā)流量
  • queueCapacity:緩沖任務,防止雪崩
  • RejectedExecutionHandler:選擇 CallerRunsPolicy 實現(xiàn)自然限流

4.3 線程池定位

  • Web 請求內(nèi)使用
  • IO + 輕計算混合型線程池
  • 非長任務、非阻塞型任務

五、核心業(yè)務實現(xiàn)

5.1 校驗 Service(模擬 RPC / DB)

@Service
public class OrderCheckService {

    public boolean checkStock(Long skuId) {
        sleep(100);
        return true;
    }

    public boolean checkUser(Long userId) {
        sleep(80);
        return true;
    }

    public int calcPrice(Long skuId) {
        sleep(120);
        return 99;
    }

    private void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

5.2 訂單創(chuàng)建核心邏輯

@Service
public class OrderService {

    @Resource(name = "orderExecutor")
    private Executor orderExecutor;

    @Autowired
    private OrderCheckService orderCheckService;

    public String createOrder(Long userId, Long skuId) throws Exception {

        long start = System.currentTimeMillis();

        CompletableFuture<Boolean> stockFuture =
                CompletableFuture.supplyAsync(
                        () -> orderCheckService.checkStock(skuId),
                        orderExecutor);

        CompletableFuture<Boolean> userFuture =
                CompletableFuture.supplyAsync(
                        () -> orderCheckService.checkUser(userId),
                        orderExecutor);

        CompletableFuture<Integer> priceFuture =
                CompletableFuture.supplyAsync(
                        () -> orderCheckService.calcPrice(skuId),
                        orderExecutor);

        CompletableFuture.allOf(
                stockFuture, userFuture, priceFuture).join();

        if (!stockFuture.get()) {
            throw new RuntimeException("庫存不足");
        }

        int price = priceFuture.get();

        lockStock(skuId);
        saveOrder(userId, skuId, price);

        return "success, cost=" +
                (System.currentTimeMillis() - start) + "ms";
    }

    private void lockStock(Long skuId) {
        sleep(50);
    }

    private void saveOrder(Long userId, Long skuId, int price) {
        sleep(80);
    }

    private void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

5.3 Controller

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/create")
    public String createOrder(
            @RequestParam Long userId,
            @RequestParam Long skuId) throws Exception {
        return orderService.createOrder(userId, skuId);
    }
}

六、JMeter 壓測與結果分析

6.1 壓測配置說明

  • 并發(fā)線程數(shù):200
  • Ramp-Up:1 秒

6.2 壓測現(xiàn)象

系統(tǒng)啟動初期:

  • 接口 RT ≈ 288ms

持續(xù)壓測后:

  • RT 逐漸上升
  • 峰值約 1888ms

6.3 原因分析

  • 每個請求會向線程池提交 3 個并行任務
  • 200 個并發(fā)請求 ≈ 600 個線程池任務
  • 線程池最大并發(fā)執(zhí)行數(shù)為 16
  • 多余任務進入阻塞隊列
  • 隊列滿后觸發(fā)CallerRunsPolicy
  • 部分任務由 HTTP 工作線程執(zhí)行,導致請求處理時間變長

6.4 工程結論

  • RT 上升并不代表線程池失效
  • 這是線程池在高并發(fā)下的自我保護行為
  • 相比無限創(chuàng)建線程導致系統(tǒng)崩潰,RT 變慢是一種可接受的退化方式

線程池優(yōu)化的是系統(tǒng)吞吐與穩(wěn)定性,而不是在無限并發(fā)下保持恒定響應時間。

七、問題思考

7.1 為什么不用 @Async?

  • 難以進行復雜任務編排
  • 不利于精細化控制線程池

7.2 為什么不用 parallelStream?

  • 使用公共 ForkJoinPool
  • 線程資源不可控

7.3 線程池并非萬能

  • 仍需配合限流、熔斷等機制
  • 核心鏈路與非核心鏈路應區(qū)別對待

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java實現(xiàn)添加條形碼到PDF表格的方法詳解

    Java實現(xiàn)添加條形碼到PDF表格的方法詳解

    條碼的應用已深入生活和工作的方方面面。本文以操作PDF文件為例,介紹如何利用Java語言在編輯表格時,向單元格中添加條形碼,感興趣的可以學習一下
    2022-06-06
  • Java詳解swagger2如何配置使用

    Java詳解swagger2如何配置使用

    編寫和維護接口文檔是每個程序員的職責,根據(jù)Swagger2可以快速幫助我們編寫最新的API接口文檔,再也不用擔心開會前仍忙于整理各種資料了,間接提升了團隊開發(fā)的溝通效率
    2022-06-06
  • JDBC簡介_動力節(jié)點Java學院整理

    JDBC簡介_動力節(jié)點Java學院整理

    什么是JDBC?這篇文章就為大家詳細介紹了Java語言中用來規(guī)范客戶端程序如何來訪問數(shù)據(jù)庫的應用程序接口,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • SpringBoot3.x中spring.factories?SPI?服務發(fā)現(xiàn)機制的改變問題小結

    SpringBoot3.x中spring.factories?SPI?服務發(fā)現(xiàn)機制的改變問題小結

    spring.factories其實是SpringBoot提供的SPI機制,底層實現(xiàn)是基于SpringFactoriesLoader檢索ClassLoader中所有jar引入的META-INF/spring.factories文件,這篇文章主要介紹了SpringBoot3.x中spring.factories?SPI?服務發(fā)現(xiàn)機制的改變,需要的朋友可以參考下
    2023-05-05
  • IDEA入門級使用教程你居然還在用eclipse?

    IDEA入門級使用教程你居然還在用eclipse?

    上個月,idea的使用量超越eclipse的消息席卷了整個IT界,idea到底好在哪里呢?下面小編通過本文給大家詳細介紹下IDEA入門級使用教程,非常詳細,感興趣的朋友一起看看吧
    2020-10-10
  • Java開發(fā)或調(diào)用WebService的幾種方式總結

    Java開發(fā)或調(diào)用WebService的幾種方式總結

    java開發(fā)過程中,很多地方都會遇到數(shù)據(jù)傳遞,遠程獲取數(shù)據(jù)問題,這篇文章主要介紹了Java開發(fā)或調(diào)用WebService的幾種方式的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-06-06
  • Java簡單有效實現(xiàn)將PDF轉(zhuǎn)換為TIFF圖片

    Java簡單有效實現(xiàn)將PDF轉(zhuǎn)換為TIFF圖片

    在日常開發(fā)中,我們常需要將 PDF 轉(zhuǎn)換為高質(zhì)量的 TIFF 圖片,本文將通過 Java 提供一個簡單高效的解決方案,幫助你輕松完成 PDF 到 TIFF 的轉(zhuǎn)換,并支持批量與多頁處理,有需要的可以參考一下
    2025-09-09
  • JavaAPI的使用方法詳解

    JavaAPI的使用方法詳解

    這篇文章主要介紹了JavaAPI的使用方法詳解,還是比較不錯的,這里分享給大家,供需要的朋友參考。
    2017-11-11
  • Jenkins Maven pom jar打包未拉取最新包解決辦法

    Jenkins Maven pom jar打包未拉取最新包解決辦法

    包版本號未變更新后,jenkins打包不會拉取最新包,本文主要介紹了Jenkins Maven pom jar打包未拉取最新包解決辦法,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • 在mybatis執(zhí)行SQL語句之前進行攔擊處理實例

    在mybatis執(zhí)行SQL語句之前進行攔擊處理實例

    本篇文章主要介紹了在mybatis執(zhí)行SQL語句之前進行攔擊處理實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04

最新評論

昌邑市| 六枝特区| 宜春市| 玉溪市| 福鼎市| 阳高县| 河源市| 玉屏| 洞口县| 福泉市| 鄂托克旗| 石阡县| 出国| 右玉县| 定远县| 宁南县| 伊吾县| 临漳县| 沁水县| 班玛县| 屏东县| 五家渠市| 丰镇市| 昭苏县| 吉木乃县| 汾西县| 汶川县| 开封市| 宁武县| 宕昌县| 水富县| 赣州市| 襄汾县| 榆中县| 浦北县| 蚌埠市| 铁岭市| 汕尾市| 通道| 全南县| 晋宁县|