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

Java中大量閑置MySQL連接的解決方案

 更新時(shí)間:2025年12月29日 10:02:10   作者:winfield821  
大量閑置 MySQL 連接會(huì)直接導(dǎo)致 MySQL 連接數(shù)耗盡(Too many connections)、服務(wù)器資源(內(nèi)存/文件句柄)浪費(fèi)、數(shù)據(jù)庫(kù)響應(yīng)變慢等問(wèn)題,所以本文給大家介紹了Java中大量閑置MySQL連接的解決方案,需要的朋友可以參考下

引言

大量閑置 MySQL 連接會(huì)直接導(dǎo)致 MySQL 連接數(shù)耗盡(Too many connections)、服務(wù)器資源(內(nèi)存/文件句柄)浪費(fèi)、數(shù)據(jù)庫(kù)響應(yīng)變慢等問(wèn)題。核心解決思路是:先緊急回收閑置連接→再定位根因→最后通過(guò)代碼/連接池/MySQL 配置從根本避免,以下是分步驟的實(shí)操方案。

一、閑置連接的核心危害與識(shí)別方法

1. 閑置連接的危害

  • 占用 MySQL 全局連接數(shù)(由 max_connections 限制),導(dǎo)致新請(qǐng)求無(wú)法獲取連接,拋出 Too many connections
  • 每個(gè) MySQL 連接占用約 100KB~1MB 內(nèi)存,大量閑置連接會(huì)耗盡數(shù)據(jù)庫(kù)服務(wù)器內(nèi)存;
  • 閑置連接若長(zhǎng)期不釋放,可能因 MySQL 端 wait_timeout 被強(qiáng)制斷開(kāi),導(dǎo)致 Java 代碼出現(xiàn)「閉連接異?!?。

2. 如何識(shí)別閑置連接

(1)MySQL 端查看(直接定位閑置連接)

執(zhí)行 SQL 查看所有連接狀態(tài),State = Sleep 代表閑置連接:

-- 查看所有連接(關(guān)注 State、Time、User、Host 列)
show processlist;

-- 統(tǒng)計(jì)閑置連接數(shù)(Sleep 狀態(tài)且閑置超 60 秒)
SELECT COUNT(*) FROM information_schema.processlist WHERE STATE = 'Sleep' AND TIME > 60;
  • Time 列:連接閑置的秒數(shù);
  • State = Sleep:連接處于空閑狀態(tài),無(wú) SQL 執(zhí)行;
  • 正常閑置連接數(shù)應(yīng)遠(yuǎn)小于 max_connections(建議<20%)。

(2)Java 連接池監(jiān)控(定位應(yīng)用側(cè)問(wèn)題)

通過(guò)連接池自帶監(jiān)控(如 Druid 監(jiān)控頁(yè)、HikariCP 日志)查看:

  • 「空閑連接數(shù)」:長(zhǎng)期遠(yuǎn)大于「活躍連接數(shù)」;
  • 「連接泄露」:連接借出后未歸還(Druid 可直接定位泄露的代碼棧)。

二、閑置連接的核心根因

根因分類(lèi)具體場(chǎng)景
代碼層面(最常見(jiàn))1. 未關(guān)閉連接(try 塊中獲取連接,未在 finally/try-with-resources 中 close);
2. 連接復(fù)用差(每次請(qǐng)求新建連接,未用連接池);
3. 連接泄露(連接借出后未歸還,如線(xiàn)程池持有連接不釋放);
連接池配置不合理1. 最小空閑連接(minimumIdle)設(shè)置過(guò)大,連接池長(zhǎng)期維持大量空閑連接;
2. 空閑超時(shí)(idleTimeout)未配置/設(shè)置過(guò)長(zhǎng),閑置連接不回收;
3. 最大連接數(shù)(maximumPoolSize)設(shè)置過(guò)大,超出業(yè)務(wù)實(shí)際需求;
MySQL 端配置wait_timeout 過(guò)大(默認(rèn) 8 小時(shí)),MySQL 不主動(dòng)斷開(kāi)閑置連接;
連接池使用不當(dāng)1. 多數(shù)據(jù)源未隔離,連接池配置復(fù)用導(dǎo)致閑置;
2. 連接池單例失效,創(chuàng)建多個(gè)連接池實(shí)例;

三、分步驟解決閑置連接問(wèn)題

步驟 1:緊急回收閑置連接(止損優(yōu)先)

若已出現(xiàn)連接耗盡/大量閑置,先快速回收,避免業(yè)務(wù)中斷:

-- 殺死閑置超 60 秒的 Sleep 連接(替換為實(shí)際閾值)
SELECT CONCAT('KILL ', id, ';') FROM information_schema.processlist 
WHERE STATE = 'Sleep' AND TIME > 60 INTO OUTFILE '/tmp/kill_idle_connections.sql';

-- 執(zhí)行生成的 kill 語(yǔ)句(謹(jǐn)慎:避免殺死業(yè)務(wù)連接)
SOURCE /tmp/kill_idle_connections.sql;

注意:僅清理「確認(rèn)閑置」的連接(最好在非業(yè)務(wù)高峰期操作),避免誤殺活躍連接。

步驟 2:修復(fù)代碼層面的連接泄露

90% 的閑置連接問(wèn)題源于代碼未正確釋放連接,核心是「確保連接用完即還」,以下是錯(cuò)誤 vs 正確示例:

錯(cuò)誤示例(未關(guān)閉連接,導(dǎo)致連接泄露/閑置)

// 錯(cuò)誤:連接未關(guān)閉,借出后無(wú)法歸還到連接池,最終成為閑置/泄露連接
public void queryData() {
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;
    try {
        // 從連接池獲取連接
        conn = DataSourceUtils.getConnection(dataSource);
        stmt = conn.createStatement();
        rs = stmt.executeQuery("SELECT * FROM user");
        // 業(yè)務(wù)邏輯...
    } catch (SQLException e) {
        e.printStackTrace();
    }
    // 未在 finally 中關(guān)閉連接!
}

正確示例 1:try-with-resources(推薦,自動(dòng)關(guān)閉)

Java 7+ 支持,實(shí)現(xiàn) AutoCloseable 的對(duì)象(Connection/Statement/ResultSet)會(huì)自動(dòng)關(guān)閉:

public void queryData() {
    // try-with-resources 自動(dòng)關(guān)閉連接、Statement、ResultSet
    try (Connection conn = DataSourceUtils.getConnection(dataSource);
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT * FROM user")) {
        // 業(yè)務(wù)邏輯...
    } catch (SQLException e) {
        e.printStackTrace();
    }
    // 無(wú)需手動(dòng) close,JVM 自動(dòng)釋放連接到連接池
}

正確示例 2:finally 手動(dòng)關(guān)閉(兼容低版本 Java)

public void queryData() {
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;
    try {
        conn = DataSourceUtils.getConnection(dataSource);
        stmt = conn.createStatement();
        rs = stmt.executeQuery("SELECT * FROM user");
        // 業(yè)務(wù)邏輯...
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 逆序關(guān)閉資源,避免內(nèi)存泄漏
        if (rs != null) {
            try { rs.close(); } catch (SQLException e) {}
        }
        if (stmt != null) {
            try { stmt.close(); } catch (SQLException e) {}
        }
        if (conn != null) {
            try { 
                // 歸還連接到連接池(而非真正關(guān)閉)
                DataSourceUtils.releaseConnection(conn, dataSource); 
            } catch (SQLException e) {}
        }
    }
}

步驟 3:優(yōu)化連接池配置

Java 項(xiàng)目幾乎都用連接池(HikariCP 是 Spring Boot 默認(rèn),Druid 是阿里開(kāi)源),通過(guò)合理配置從根本減少閑置連接。通常修改的連接池配置:

  • 降低最小空閑連接數(shù)(minimumIdle=0
  • 縮短空閑超時(shí)(idleTimeout=60000,1 分鐘)
  • 暫時(shí)降低最大連接數(shù)(maximumPoolSize)至業(yè)務(wù)實(shí)際需求

(1)HikariCP 最優(yōu)配置(Spring Boot 示例)

application.yml 配置:

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      # 核心配置(重點(diǎn))
      maximum-pool-size: 10  # 最大連接數(shù):按業(yè)務(wù)QPS調(diào)整(8核16G服務(wù)器建議10-20)
      minimum-idle: 0        # 最小空閑連接:設(shè)為0(Hikari默認(rèn)),避免長(zhǎng)期閑置
      idle-timeout: 60000    # 空閑超時(shí):1分鐘(閑置超1分鐘回收)
      max-lifetime: 1800000  # 連接最大生命周期:30分鐘(避免連接長(zhǎng)期閑置)
      connection-timeout: 3000 # 獲取連接超時(shí):3秒(超時(shí)則拋異常,避免等待無(wú)效連接)
      # 輔助配置
      pool-name: MyHikariPool # 連接池名稱(chēng),便于監(jiān)控
      connection-test-query: SELECT 1 # 借連接時(shí)校驗(yàn)連接可用性(避免使用閉連接)

關(guān)鍵參數(shù)解釋

  • minimum-idle: 0:HikariCP 會(huì)根據(jù)業(yè)務(wù)需求動(dòng)態(tài)創(chuàng)建/銷(xiāo)毀連接,無(wú)閑置連接堆積;
  • idle-timeout: 60000:閑置 1 分鐘的連接直接回收,避免長(zhǎng)期占著連接池;
  • max-lifetime: 1800000:強(qiáng)制回收使用超 30 分鐘的連接,避免 MySQL 端因 wait_timeout 斷開(kāi)。

(2)Druid 最優(yōu)配置(適合需要監(jiān)控的場(chǎng)景)

Druid 自帶連接泄露監(jiān)控,配置示例:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      # 核心配置
      max-active: 10        # 最大連接數(shù)(同Hikari maximum-pool-size)
      min-idle: 0           # 最小空閑連接
      max-wait: 3000        # 獲取連接超時(shí)
      time-between-eviction-runs-millis: 60000 # 空閑連接檢測(cè)周期:1分鐘
      min-evictable-idle-time-millis: 60000    # 閑置超1分鐘回收
      max-evictable-idle-time-millis: 1800000  # 連接最大閑置時(shí)間:30分鐘
      validation-query: SELECT 1
      test-while-idle: true # 空閑時(shí)校驗(yàn)連接可用性
      # 監(jiān)控配置(定位連接泄露)
      filters: stat,wall,log4j2
      web-stat-filter:
        enabled: true
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/* # 訪(fǎng)問(wèn) http://ip:port/druid 查看連接池監(jiān)控
        login-username: admin
        login-password: admin
      # 連接泄露監(jiān)控(關(guān)鍵)
      remove-abandoned: true # 開(kāi)啟泄露連接回收
      remove-abandoned-timeout: 300 # 連接借出超5分鐘未歸還,強(qiáng)制回收
      log-abandoned: true # 打印泄露連接的代碼棧(便于定位)

步驟 4:適配 MySQL 端配置

調(diào)整 MySQL 配置,讓數(shù)據(jù)庫(kù)主動(dòng)清理閑置連接。

需重啟 MySQL:

# my.cnf / my.ini 配置
[mysqld]
max_connections = 1000        # 全局最大連接數(shù)(按服務(wù)器配置調(diào)整)
wait_timeout = 600            # 連接閑置超 10 分鐘,MySQL 主動(dòng)斷開(kāi)(建議 60~600 秒)
interactive_timeout = 600     # 與 wait_timeout 保持一致(交互式連接超時(shí))

動(dòng)態(tài)生效(無(wú)需重啟):

SET GLOBAL wait_timeout = 600;
SET GLOBAL interactive_timeout = 600;

注意:wait_timeout 需 ≤ 連接池的 max-lifetime(如連接池設(shè) 30 分鐘,MySQL 設(shè) 10 分鐘),避免 MySQL 先斷開(kāi)連接,導(dǎo)致 Java 代碼使用閉連接。

步驟 5:監(jiān)控與預(yù)警

通過(guò)監(jiān)控提前發(fā)現(xiàn)閑置/泄露連接,避免問(wèn)題擴(kuò)大:

(1)連接池監(jiān)控

  • Druid:訪(fǎng)問(wèn) /druid 監(jiān)控頁(yè),查看「活躍連接數(shù)」「空閑連接數(shù)」「連接泄露數(shù)」;
  • HikariCP:通過(guò) HikariPoolMXBean 暴露監(jiān)控指標(biāo),接入 Prometheus + Grafana:
    // 獲取 Hikari 監(jiān)控指標(biāo)
    HikariDataSource ds = (HikariDataSource) dataSource;
    HikariPoolMXBean poolMXBean = ds.getHikariPoolMXBean();
    System.out.println("空閑連接數(shù):" + poolMXBean.getIdleConnections());
    System.out.println("活躍連接數(shù):" + poolMXBean.getActiveConnections());
    

(2)MySQL 監(jiān)控

  • 監(jiān)控 show processlistSleep 連接數(shù),超過(guò)閾值(如 50)則告警;
  • 監(jiān)控 max_connections 使用率,超過(guò) 80% 則告警。

(3)業(yè)務(wù)監(jiān)控

  • 監(jiān)控「獲取連接耗時(shí)」:耗時(shí)突增可能是連接池耗盡/閑置連接過(guò)多;
  • 監(jiān)控「SQL 執(zhí)行異?!梗喝?Communications link failure(連接被 MySQL 斷開(kāi))。

四、一些最佳實(shí)踐(避免閑置連接的核心原則)

  1. 強(qiáng)制使用連接池:禁止手動(dòng)創(chuàng)建 DriverManager.getConnection()(每次新建連接,用完未關(guān)即閑置);
  2. 連接池參數(shù)標(biāo)準(zhǔn)化
    • 最大連接數(shù):按「CPU 核心數(shù) × 2 + 磁盤(pán)數(shù)」或業(yè)務(wù) QPS 調(diào)整(如 8 核服務(wù)器設(shè) 10~20);
    • 最小空閑連接:一律設(shè) 0(讓連接池動(dòng)態(tài)伸縮);
    • 空閑超時(shí):1~5 分鐘,最大生命周期:30 分鐘;
  3. 代碼規(guī)范:所有數(shù)據(jù)庫(kù)操作必須用 try-with-resourcesfinally 關(guān)閉連接;
  4. 定期巡檢:每周查看 MySQL 連接狀態(tài)、連接池監(jiān)控,排查閑置/泄露連接;
  5. 壓測(cè)驗(yàn)證:上線(xiàn)前壓測(cè),驗(yàn)證連接池配置是否匹配業(yè)務(wù)峰值,避免閑置/耗盡。

總結(jié)

解決大量閑置 MySQL 連接的核心邏輯是:

  1. 緊急止損:手動(dòng)清理閑置連接 + 臨時(shí)調(diào)整連接池配置;
  2. 根因治理:修復(fù)代碼連接泄露 + 優(yōu)化連接池/MySQL 配置;
  3. 長(zhǎng)期預(yù)防:監(jiān)控預(yù)警 + 規(guī)范代碼/配置。

其中,代碼層面的連接釋放規(guī)范是最核心的環(huán)節(jié),連接池配置優(yōu)化是關(guān)鍵手段,兩者結(jié)合可從根本解決閑置連接問(wèn)題。

以上就是Java中大量閑置MySQL連接的解決方案的詳細(xì)內(nèi)容,更多關(guān)于Java大量閑置MySQL連接的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java之Spring AOP 實(shí)現(xiàn)用戶(hù)權(quán)限驗(yàn)證

    Java之Spring AOP 實(shí)現(xiàn)用戶(hù)權(quán)限驗(yàn)證

    本篇文章主要介紹了Java之Spring AOP 實(shí)現(xiàn)用戶(hù)權(quán)限驗(yàn)證,用戶(hù)登錄、權(quán)限管理這些是必不可少的業(yè)務(wù)邏輯,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2017-02-02
  • Spring?InitializingBean的使用方式

    Spring?InitializingBean的使用方式

    InitializingBean是Spring框架中的一個(gè)生命周期接口,用于在Bean的屬性設(shè)置完成后執(zhí)行自定義的初始化邏輯,本文給大家介紹spring?InitializingBean的使用方式,感興趣的朋友小編一起看看吧
    2026-01-01
  • java布局管理之CardLayout簡(jiǎn)單實(shí)例

    java布局管理之CardLayout簡(jiǎn)單實(shí)例

    這篇文章主要為大家詳細(xì)介紹了java布局管理之CardLayout的簡(jiǎn)單實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Spring依賴(lài)注入和控制反轉(zhuǎn)詳情

    Spring依賴(lài)注入和控制反轉(zhuǎn)詳情

    這篇文章主要介紹了Spring依賴(lài)注入和控制反轉(zhuǎn)詳情,控制反轉(zhuǎn)是面向?qū)ο缶幊讨惺褂玫男g(shù)語(yǔ),通過(guò)該術(shù)語(yǔ),對(duì)象或?qū)ο蠹目刂茩?quán)被賦予框架或由框架提供的容器。下文更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05
  • SpringBoot配置外部靜態(tài)資源映射問(wèn)題

    SpringBoot配置外部靜態(tài)資源映射問(wèn)題

    這篇文章主要介紹了SpringBoot配置外部靜態(tài)資源映射問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • springboot啟動(dòng)時(shí)運(yùn)行代碼詳解

    springboot啟動(dòng)時(shí)運(yùn)行代碼詳解

    在本篇內(nèi)容中我們給大家整理了關(guān)于在springboot啟動(dòng)時(shí)運(yùn)行代碼的詳細(xì)圖文步驟以及需要注意的地方講解,有興趣的朋友們學(xué)習(xí)下。
    2019-06-06
  • Spring5使用JSR 330標(biāo)準(zhǔn)注解的方法

    Spring5使用JSR 330標(biāo)準(zhǔn)注解的方法

    從Spring3.0之后,除了Spring自帶的注解,我們也可以使用JSR330的標(biāo)準(zhǔn)注解,本文主要介紹了Spring5使用JSR 330標(biāo)準(zhǔn)注解,感興趣的可以了解一下
    2021-09-09
  • java實(shí)現(xiàn)文件切片上傳百度云+斷點(diǎn)續(xù)傳的方法

    java實(shí)現(xiàn)文件切片上傳百度云+斷點(diǎn)續(xù)傳的方法

    文件續(xù)傳在很多地方都可以用的到,本文主要介紹了java實(shí)現(xiàn)文件切片上傳百度云+斷點(diǎn)續(xù)傳的方法,?文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • SpringMVC核心技術(shù)

    SpringMVC核心技術(shù)

    這篇文章主要介紹了SpringMVC入門(mén)實(shí)例,在springmvc入門(mén)教程里算是比較不錯(cuò)的,結(jié)構(gòu)也比較完整,需要的朋友可以參考。希望可以幫助到你
    2021-07-07
  • Logback日志基礎(chǔ)及自定義配置代碼實(shí)例

    Logback日志基礎(chǔ)及自定義配置代碼實(shí)例

    這篇文章主要介紹了Logback日志基礎(chǔ)及自定義配置代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評(píng)論

福海县| 北宁市| 田东县| 陈巴尔虎旗| 兴安盟| 新乡市| 长阳| 龙井市| 正宁县| 颍上县| 潮安县| 新密市| 奉化市| 宜丰县| 安丘市| 正蓝旗| 广西| 通江县| 来安县| 莱阳市| 广宗县| 弥勒县| 句容市| 万州区| 柘荣县| 河东区| 册亨县| 商都县| 禹城市| 拜城县| 安图县| 曲阜市| 墨脱县| 温州市| 眉山市| 石屏县| 长阳| 牙克石市| 桂东县| 万宁市| 时尚|