spring boot 項目中數據庫連接池的配置問題研究

重要:SpringBoot 2.0 開始推 HikariCP ,將默認的數據庫連接池從 tomcat jdbc pool 改為了 hikari , HikariCP 在性能和并發方面確實表現不俗(號稱最快的連接池)。

一、當我們遇到這個問題該怎么辦?用戶“***”連接超過了最大資源數。

考慮修改數據庫連接池的默認設置或者不使用數據庫連接池技術;

二、什么是數據庫連接池技術?

數據庫連接池是不需要用戶申請和釋放數據庫的連接,他會自動幫您管理數據庫的連接用戶只管使用這個連接,連接池會自動釋放已經用過的連接,當連接不夠用的時候他會自動申請新的連接,這樣循環周而復始,保證數據庫連接的可用性。大家可以理解為連接池是自動幫助用戶管理數據庫的連接的地方,這樣就不會發生上面的數據庫連接忘記關閉的問題

? 數據庫連接池會在tomcat啟動的時候就自動申請好數據庫連接(申請多少數據庫連接根據您的配置文件里設置的決定的),放在一個虛擬的池子里面,您調用數據庫的時候從這個池子里拿,用完了池子會自動回收你已經用過的這個連接,為下一個連接做準備!

? 使用了數據庫連接池,連接池會有一個配置文件,配置文件里可以規定他在啟動的時候申請最大多少個連接,最小多少個連接,初始多少個連接,一個連接可以存活多久等。

三、為什么要使用數據庫連接池技術?

1、數據庫并發,數據庫同時可以被多個人操作,或者多個客戶端請求連接數據庫;

2、部分用戶申請完數據庫連接后,忘記關閉這個數據庫連接(這樣的問題由于程序員的大意也是時有發生的);

這時候就需要一個中間件管理連接,協助用戶進行申請和釋放數據庫的鏈接。事先創建好數據庫連接放在“數據庫連接池”中等你來用,用完了就釋放,這樣就避免了每次請求連接數據庫都要創建連接,節省資源,縮短反應時間。數據庫連接池負責分配,管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而不是重新建立一個。


使用數據庫連接池技術的示意圖

數據庫連接池在初始化時將創建一定數量的數據庫連接放到連接池中, 這些數據庫連接的數量是由最小數據庫連接數來設定的.無論這些數據庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量.連接池的最大數據庫連接數量限定了這個連接池能占有的最大連接數,當應用程序向連接池請求的連接數超過最大連接數量時,這些請求將被加入到等待隊列中.

? 數據庫連接池的最小連接數和最大連接數的設置要考慮到以下幾個因素:

最小連接數:是連接池一直保持的數據庫連接,所以如果應用程序對數據庫連接的使用量不大,將會有大量的數據庫連接資源被浪費.

最大連接數:是連接池能申請的最大連接數,如果數據庫連接請求超過次數,后面的數據庫連接請求將被加入到等待隊列中,這會影響以后的數據庫操作

如果最小連接數與最大連接數相差很大:那么最先連接請求將會獲利,之后超過最小連接數量的連接請求等價于建立一個新的數據庫連接.不過,這些大于最小連接數的數據庫連接在使用完不會馬上被釋放,他將被放到連接池中等待重復使用或是空間超時后被釋放.

四、如何設置連接池

根據自己程序的并發個數;

以20個并發為例子 連接池我們建議設置

最大連接為:19

最小連接為:5

初始連接為:5

過期時間為:120秒

如果并發是30個的話只需要把上面的最大連接數設置為29個即可,其他的不變。如果把最小連接數和初始連接數設置過大,則會影響數據庫連接池的性能。

可以參考:http://www.jspkongjian.net/news.jsp?id=790

五、spring boot項目的連接池技術研究

創建Spring boot 項目使用spring-boot-starter-data-jpa,POM下載的依賴包里會包含spring-boot-starter-jdbc的依賴包,該依賴包綁定com.zaxxer:HikariCP.


控制臺獲取信息


找到相應的jar包

看看這里的默認配置

找到直接使用的配置文件源碼來看看,如下:


HikariDataSource源碼

HikariDataSource繼承HikariConfig實現了接口DataSource, Closeable兩個接口。

再來看看HikariConfig的源碼:


默認配置都在這里

簡書不合適貼代碼,但還是貼出來,免得大家再去找:

public class HikariConfigimplements HikariConfigMXBean

{

private static final LoggerLOGGER = LoggerFactory.getLogger(HikariConfig.class);

private static final char[]ID_CHARACTERS ="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();

private static final long CONNECTION_TIMEOUT =SECONDS.toMillis(30);

private static final long VALIDATION_TIMEOUT =SECONDS.toMillis(5);

private static final long IDLE_TIMEOUT =MINUTES.toMillis(10);

private static final long MAX_LIFETIME =MINUTES.toMillis(30);

private static final int DEFAULT_POOL_SIZE =10;

private static boolean unitTest =false;

// Properties changeable at runtime through the HikariConfigMXBean

//

? private volatile long connectionTimeout;

private volatile long validationTimeout;

private volatile long idleTimeout;

private volatile long leakDetectionThreshold;

private volatile long maxLifetime;

private volatile int maxPoolSize;

private volatile int minIdle;

private volatile Stringusername;

private volatile Stringpassword;

// Properties NOT changeable at runtime

//

? private long initializationFailTimeout;

private Stringcatalog;

private StringconnectionInitSql;

private StringconnectionTestQuery;

private StringdataSourceClassName;

private StringdataSourceJndiName;

private StringdriverClassName;

private StringjdbcUrl;

private StringpoolName;

private Stringschema;

private StringtransactionIsolationName;

private boolean isAutoCommit;

private boolean isReadOnly;

private boolean isIsolateInternalQueries;

private boolean isRegisterMbeans;

private boolean isAllowPoolSuspension;

private DataSourcedataSource;

private PropertiesdataSourceProperties;

private ThreadFactorythreadFactory;

private ScheduledExecutorServicescheduledExecutor;

private MetricsTrackerFactorymetricsTrackerFactory;

private ObjectmetricRegistry;

private ObjecthealthCheckRegistry;

private PropertieshealthCheckProperties;

private volatile boolean sealed;

/**

* Default constructor

*/

? public HikariConfig()

{

dataSourceProperties =new Properties();

healthCheckProperties =new Properties();

minIdle = -1;

maxPoolSize = -1;

maxLifetime =MAX_LIFETIME;

connectionTimeout =CONNECTION_TIMEOUT;

validationTimeout =VALIDATION_TIMEOUT;

idleTimeout =IDLE_TIMEOUT;

initializationFailTimeout =1;

isAutoCommit =true;

String systemProp = System.getProperty("hikaricp.configurationFile");

if (systemProp !=null) {

loadProperties(systemProp);

}

}

仔細看一下,發現初始化配置有3種方式:

第一種:Default constructor

假如我們不寫自己的配置時,就使用這個構造器中的默認參數初始化;

minIdle = -1;

maxPoolSize = -1;

maxLifetime =MAX_LIFETIME;? //30s

connectionTimeout =CONNECTION_TIMEOUT;? //30s

validationTimeout =VALIDATION_TIMEOUT;? ? // 5s

idleTimeout =IDLE_TIMEOUT;? // 10s

initializationFailTimeout =1;

isAutoCommit =true;

默認的連接池的大小是10;

final int DEFAULT_POOL_SIZE =10;


第二種:大概就是根據我們在spring boot 項目中的 properties.yml文件中設置的屬性

/**

* Construct a HikariConfig from the specified properties object.

*

* @param properties the name of the property file

*/

第三種:根據file類型的配置文件

/**

* Construct a HikariConfig from the specified property file name.? <code>propertyFileName</code>* will first be treated as a path in the file-system, and if that fails the

* Class.getResourceAsStream(propertyFileName) will be tried.

*

* @param propertyFileName the name of the property file

*/

有個大哥總結了一下:https://blog.csdn.net/MyHerux/article/details/80730690

阿里的數據庫連接池技術研究:https://www.cnblogs.com/wuyun-blog/p/5679073.html

研究這一問題的起因:


局部


全局

2018-12-05 16:39:12.566 ERROR 5712 --- [? ? ? ? ? main] o.h.engine.jdbc.spi.SqlExceptionHelper? : User 'root' has exceeded the 'max_connections_per_hour' resource (current value: 100)

root用戶每一個小時連接資源的次數超過了100次,連接被拒絕!

怎么辦,難道我在這里坐著等一個小時以后再調試,顯然不可以,不能打著技術“瓶頸”的幌子“磨洋工”。于是,我試著解決這一報錯。

最簡單的解決辦法:


停止MySQL Server,重啟

,轉了一圈發現根本不是我改配置能解決的,用這招輕松解決。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,781評論 18 139
  • 本文是我自己在秋招復習時的讀書筆記,整理的知識點,也是為了防止忘記,尊重勞動成果,轉載注明出處哦!如果你也喜歡,那...
    波波波先森閱讀 11,289評論 4 56
  • 2005年4月份,我本想靠一個羊屎蛋換畢業證書,但是事與愿違,經歷過那么多的波折,我即將上大學八年級。這句話的意思...
    國產大青蛙閱讀 538評論 0 0
  • 今年一月,我收到了小學同學結婚的消息,她讓我們幾個玩的最好的朋友一起去做伴娘,就在明天,她就要出嫁了。 以前我就說...
    蘇溪閱讀 497評論 0 1
  • 刷朋友圈對我是個很嚴峻的考驗,你知道的,像我這樣一個大好青年,朋友圈也凈是些大好青年,外加大好娃娃。曬娃黨孜孜不倦...
    微冷微冷閱讀 35,514評論 29 43