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

簡(jiǎn)單聊聊SpringBoot性能優(yōu)化的12個(gè)小技巧

 更新時(shí)間:2025年05月26日 08:14:24   作者:蘇三說(shuō)技術(shù)  
這篇文章主要想來(lái)和大家簡(jiǎn)單聊聊SpringBoot性能優(yōu)化的12個(gè)小技巧,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以了解一下

前言

不知道你在SpringBoot項(xiàng)目中,有沒(méi)有遇到過(guò)下面這樣的代碼:

@GetMapping("/orders")
public List<Order> listOrders() {
    return orderDao.findAll(); 
}

一次性查詢(xún)了所有的訂單,全表掃描50萬(wàn)數(shù)據(jù),導(dǎo)致接口查詢(xún)性能很差,嚴(yán)重的時(shí)候可能會(huì)導(dǎo)致OOM問(wèn)題。

問(wèn)題定位

  • 未分頁(yè)查詢(xún)
  • 無(wú)緩存機(jī)制
  • 未啟用批量處理

這次事故讓我明白:性能優(yōu)化必須貫穿開(kāi)發(fā)全流程

今天這篇文章,跟大家一起聊聊SpringBoot優(yōu)化的12招,希望對(duì)你會(huì)有所幫助。

第1招:連接池參數(shù)調(diào)優(yōu)

問(wèn)題場(chǎng)景:默認(rèn)配置導(dǎo)致連接池資源浪費(fèi),高并發(fā)時(shí)出現(xiàn)連接等待

錯(cuò)誤配置

spring:
  datasource:
    hikari:
      maximum-pool-size: 1000 
      connection-timeout: 30000

數(shù)據(jù)庫(kù)連接池的最大連接數(shù),盲目設(shè)置過(guò)大,連接超時(shí)時(shí)間設(shè)置過(guò)長(zhǎng)。

優(yōu)化方案

spring:
  datasource:
    hikari:
      maximum-pool-size: ${CPU核心數(shù)*2} # 動(dòng)態(tài)調(diào)整
      minimum-idle: 5
      connection-timeout: 3000 # 3秒超時(shí)
      max-lifetime: 1800000 # 30分鐘
      idle-timeout: 600000 # 10分鐘空閑釋放

數(shù)據(jù)庫(kù)連接池的最大連接數(shù),改成根據(jù)CPU核心數(shù)動(dòng)態(tài)調(diào)整。

將連接超時(shí)時(shí)間由30000,改成3000。

第2招:JVM內(nèi)存優(yōu)化

問(wèn)題場(chǎng)景:頻繁Full GC導(dǎo)致服務(wù)卡頓

我們需要優(yōu)化JVM參數(shù)。

啟動(dòng)參數(shù)優(yōu)化

java -jar -Xms4g -Xmx4g 
-XX:NewRatio=1 
-XX:+UseG1GC 
-XX:MaxGCPauseMillis=200 
-XX:InitiatingHeapOccupancyPercent=35
-XX:+AlwaysPreTouch

最大堆內(nèi)存和初始堆內(nèi)存都設(shè)置成了4G。

-XX:NewRatio=1,設(shè)置新生代和老年代各占一半。

垃圾收集器配置的是G1。

垃圾回收的最大停頓時(shí)間為200毫秒。

第3招:關(guān)閉無(wú)用組件

問(wèn)題場(chǎng)景:自動(dòng)裝配加載不需要的Bean

優(yōu)化方案

@SpringBootApplication(exclude = {
    DataSourceAutoConfiguration.class,
    SecurityAutoConfiguration.class
})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

如果有些功能暫時(shí)用不到,可以先排除一下。

在SpringBoot項(xiàng)目啟動(dòng)的時(shí)候,排除了DataSourceAutoConfiguration和SecurityAutoConfiguration配置類(lèi)的自動(dòng)裝載。

第4招:響應(yīng)壓縮配置

問(wèn)題場(chǎng)景:接口返回JSON數(shù)據(jù)體積過(guò)大

優(yōu)化方案

server:
  compression:
    enabled: true
    mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/json
    min-response-size: 1024

配置開(kāi)啟響應(yīng)的壓縮。

第5招:請(qǐng)求參數(shù)校驗(yàn)

問(wèn)題場(chǎng)景:惡意請(qǐng)求導(dǎo)致資源耗盡

防御代碼

@GetMapping("/products")
public PageResult<Product> list(
    @RequestParam @Max(value=100, message="頁(yè)大小不能超過(guò)100") int pageSize,
    @RequestParam @Min(1) int pageNum) {
    //...
}

在接口中做好參數(shù)校驗(yàn),可以攔截很多惡意請(qǐng)求。

第6招:異步處理機(jī)制

問(wèn)題場(chǎng)景:同步處理導(dǎo)致線(xiàn)程阻塞

優(yōu)化方案

@Async("taskExecutor")
public CompletableFuture<List<Order>> asyncProcess() {
    return CompletableFuture.completedFuture(heavyProcess());
}

@Bean("taskExecutor")
public Executor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setMaxPoolSize(10);
    executor.setQueueCapacity(500);
    return executor;
}

在有些業(yè)務(wù)邏輯中,使用異步處理性能可能會(huì)更好。

第7招:使用緩存

使用緩存可以提升效率。

緩存架構(gòu)

代碼實(shí)現(xiàn)

@Cacheable(cacheNames = "products", key = "#id", 
           cacheManager = "caffeineCacheManager")
public Product getDetail(Long id) {
    return productDao.getById(id);
}

這里使用了內(nèi)存緩存。

第8招:批量操作優(yōu)化

問(wèn)題場(chǎng)景:逐條插入導(dǎo)致性能低下

優(yōu)化方案

@Transactional
public void batchInsert(List<Product> products) {
    jdbcTemplate.batchUpdate(
        "INSERT INTO product(name,price) VALUES(?,?)",
        products,
        500, // 每批數(shù)量
        (ps, product) -> {
            ps.setString(1, product.getName());
            ps.setBigDecimal(2, product.getPrice());
        });
}

每500條數(shù)據(jù)插入一次數(shù)據(jù)庫(kù)。

第9招:索引深度優(yōu)化

問(wèn)題場(chǎng)景:慢查詢(xún)?nèi)罩绢l繁出現(xiàn)全表掃描,SQL執(zhí)行時(shí)間波動(dòng)大

錯(cuò)誤案例

-- 商品表結(jié)構(gòu)
CREATE TABLE products (
    id BIGINT PRIMARY KEY,
    name VARCHAR(200),
    category VARCHAR(50),
    price DECIMAL(10,2),
    create_time DATETIME
);

-- 低效查詢(xún)
SELECT * FROM products 
WHERE category = '手機(jī)' 
AND price > 5000 
ORDER BY create_time DESC;

問(wèn)題分析

優(yōu)化方案一:聯(lián)合索引設(shè)計(jì)

索引創(chuàng)建

下面創(chuàng)建了一個(gè)分類(lèi)ID,單價(jià)和時(shí)間的聯(lián)合索引:

ALTER TABLE products 
ADD INDEX idx_category_price_create 
(category, price, create_time);

優(yōu)化方案二:覆蓋索引優(yōu)化

查詢(xún)改造

只查詢(xún)索引包含字段:

SELECT id, category, price, create_time 
FROM products 
WHERE category = '手機(jī)' 
AND price > 5000 
ORDER BY create_time DESC;

這里使用了覆蓋索引。

優(yōu)化方案三:索引失效預(yù)防

常見(jiàn)失效場(chǎng)景

案例修復(fù)

錯(cuò)誤寫(xiě)法:

SELECT * FROM products 
WHERE DATE(create_time) = '2023-01-01';

正確寫(xiě)法:

SELECT * FROM products 
WHERE create_time BETWEEN '2023-01-01 00:00:00' 
AND '2023-01-01 23:59:59';

查詢(xún)時(shí)間范圍,這里使用了BETWEEN AND關(guān)鍵字,代替了等于號(hào)。

優(yōu)化方案四:索引監(jiān)控分析

診斷命令

查看索引使用情況:

SELECT 
    index_name,
    rows_read,
    rows_selected 
FROM 
    sys.schema_index_statistics 
WHERE 
    table_name = 'products';

分析索引效率:

EXPLAIN FORMAT=JSON 
SELECT ...;

索引優(yōu)化黃金三原則

  • 最左前綴原則:聯(lián)合索引的第一個(gè)字段必須出現(xiàn)在查詢(xún)條件中
  • 短索引原則:整型字段優(yōu)先,字符串字段使用前綴索引
  • 適度索引原則:?jiǎn)蝹€(gè)表索引數(shù)量不超過(guò)5個(gè),總索引長(zhǎng)度不超過(guò)表數(shù)據(jù)量30%

DBA工具箱

  • 索引分析腳本
  • 執(zhí)行計(jì)劃可視化工具
  • 索引碎片檢測(cè)工具

第10招:自定義線(xiàn)程池

問(wèn)題場(chǎng)景:默認(rèn)線(xiàn)程池導(dǎo)致資源競(jìng)爭(zhēng)

優(yōu)化方案

@Bean("customPool")
public Executor customThreadPool() {
    return new ThreadPoolExecutor(
        10, // 核心線(xiàn)程
        50, // 最大線(xiàn)程
        60, TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(1000),
        new CustomThreadFactory(),
        new ThreadPoolExecutor.CallerRunsPolicy());
}

在高并發(fā)業(yè)務(wù)場(chǎng)景中,使用Executors類(lèi)創(chuàng)建默認(rèn)的線(xiàn)程池,可能會(huì)導(dǎo)致OOM問(wèn)題。

因此,我們需要自定義線(xiàn)程池。

第11招:熔斷限流策略

問(wèn)題場(chǎng)景:突發(fā)流量導(dǎo)致服務(wù)雪崩

解決方案

// 使用Sentinel實(shí)現(xiàn)接口限流
@SentinelResource(value = "orderQuery", 
                  blockHandler = "handleBlock",
                  fallback = "handleFallback")
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable Long id) {
    return orderService.getById(id);
}

// 限流處理
public Order handleBlock(Long id, BlockException ex) {
    throw new RuntimeException("服務(wù)繁忙,請(qǐng)稍后重試");
}

// 降級(jí)處理
public Order handleFallback(Long id, Throwable t) {
    return Order.getDefaultOrder();
}

為了解決重復(fù)流量導(dǎo)致服務(wù)雪崩的問(wèn)題,我們需要增加接口熔斷、限流和降級(jí)處理。

第12招:全鏈路監(jiān)控體系

問(wèn)題場(chǎng)景:線(xiàn)上問(wèn)題定位困難,缺乏數(shù)據(jù)支撐

我們需要增加項(xiàng)目全鏈路的監(jiān)控。

監(jiān)控方案

# SpringBoot配置
management:
  endpoints:
    web:
      exposure:
        include: "*"
  metrics:
    export:
      prometheus:
        enabled: true

這里使用了prometheus監(jiān)控。

監(jiān)控架構(gòu)

核心監(jiān)控指標(biāo)

總結(jié)

SpringBoot性能優(yōu)化檢查清單

  • 連接池參數(shù)按業(yè)務(wù)調(diào)整
  • JVM參數(shù)經(jīng)過(guò)壓測(cè)驗(yàn)證
  • 所有查詢(xún)走緩存機(jī)制
  • 批量操作替代逐條處理
  • 線(xiàn)程池按場(chǎng)景定制
  • 全鏈路監(jiān)控覆蓋

三條黃金法則

  • 預(yù)防性?xún)?yōu)化:編碼時(shí)考慮性能影響
  • 數(shù)據(jù)驅(qū)動(dòng):用監(jiān)控指標(biāo)指導(dǎo)優(yōu)化方向
  • 持續(xù)迭代:性能優(yōu)化是持續(xù)過(guò)程

性能工具包

  • Arthas在線(xiàn)診斷
  • JProfiler性能分析
  • Prometheus監(jiān)控體系

(看著監(jiān)控大屏上平穩(wěn)的QPS曲線(xiàn),我知道今晚可以睡個(gè)好覺(jué)了...)

到此這篇關(guān)于簡(jiǎn)單聊聊SpringBoot性能優(yōu)化的12個(gè)小技巧的文章就介紹到這了,更多相關(guān)SpringBoot性能優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring中的編程式事務(wù)和聲明式事務(wù)

    Spring中的編程式事務(wù)和聲明式事務(wù)

    Spring框架中,事務(wù)管理可以通過(guò)編程式事務(wù)和聲明式事務(wù)兩種方式實(shí)現(xiàn),編程式事務(wù)通過(guò)手動(dòng)編碼控制事務(wù)的開(kāi)始、提交和回滾,允許開(kāi)發(fā)者精確控制事務(wù),但增加了代碼復(fù)雜度,聲明式事務(wù)則通過(guò)@EnableTransactionManagement注解啟用事務(wù)管理
    2024-11-11
  • SpringBoot實(shí)現(xiàn)Md5對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)加密的示例

    SpringBoot實(shí)現(xiàn)Md5對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)加密的示例

    本文主要介紹了SpringBoot實(shí)現(xiàn)Md5對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)加密的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java語(yǔ)言實(shí)現(xiàn)掃雷游戲(2)

    Java語(yǔ)言實(shí)現(xiàn)掃雷游戲(2)

    這篇文章主要為大家詳細(xì)介紹了Java語(yǔ)言實(shí)現(xiàn)掃雷游戲第二部分代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 使用@ControllerAdvice同時(shí)配置過(guò)濾多個(gè)包

    使用@ControllerAdvice同時(shí)配置過(guò)濾多個(gè)包

    這篇文章主要介紹了使用@ControllerAdvice同時(shí)配置過(guò)濾多個(gè)包的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • servlet之session工作原理簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    servlet之session工作原理簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了servlet之session工作原理簡(jiǎn)介,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • java中的OPT算法實(shí)現(xiàn)方式

    java中的OPT算法實(shí)現(xiàn)方式

    這篇文章主要介紹了java中的OPT算法實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • javaweb實(shí)戰(zhàn)之商城項(xiàng)目開(kāi)發(fā)(三)

    javaweb實(shí)戰(zhàn)之商城項(xiàng)目開(kāi)發(fā)(三)

    這篇文章主要針對(duì)javaweb商城項(xiàng)目開(kāi)發(fā)進(jìn)行實(shí)戰(zhàn)演習(xí),主要實(shí)現(xiàn)通用的BaseDao.java和使用resultMap映射關(guān)聯(lián)對(duì)象,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Spring Cloud升級(jí)最新Finchley版本的所有坑

    Spring Cloud升級(jí)最新Finchley版本的所有坑

    這篇文章主要介紹了Spring Cloud升級(jí)最新Finchley版本的所有坑,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Java下載文件的四種方式詳細(xì)代碼

    Java下載文件的四種方式詳細(xì)代碼

    這篇文章介紹了Java下載文件的四種方式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Spring?Lifecycle的使用小結(jié)

    Spring?Lifecycle的使用小結(jié)

    這篇文章主要介紹了Spring?Lifecycle的使用,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05

最新評(píng)論

南江县| 名山县| 甘孜县| 阳朔县| 西城区| 钟山县| 天门市| 赞皇县| 上蔡县| 改则县| 格尔木市| 晋中市| 东丰县| 石城县| 错那县| 睢宁县| 浦东新区| 赤壁市| 疏勒县| 嫩江县| 建平县| 冀州市| 南皮县| 青川县| 同仁县| 灵台县| 小金县| 博野县| 循化| 栾川县| 中江县| 卓资县| 揭东县| 泌阳县| 裕民县| 龙山县| 商都县| 广元市| 紫阳县| 平阴县| 鹤庆县|