背景
我們自己平臺(tái)的產(chǎn)品發(fā)現(xiàn)指定的mysql數(shù)據(jù)庫(kù)后臺(tái)發(fā)現(xiàn)連接非常多燕少,過(guò)多的連接對(duì)于數(shù)據(jù)庫(kù)是一種負(fù)擔(dān)。這些連接完成SQL執(zhí)行任務(wù)后空閑著啥事也不干,白白占用內(nèi)存資源熔恢,如果這些連接堆積起來(lái),將導(dǎo)致MySQL超過(guò)最大連接數(shù)臭笆,從而無(wú)法新建MySQL連接叙淌,有可能導(dǎo)致“Too many connections”的錯(cuò)誤。
解決
1愁铺、
一反饋連接多鹰霍,我第一件事是查看mysql現(xiàn)在到底有多少連接。
SELECT count(*) FROM information_schema.PROCESSLIST WHERE DB = 'bcloud_dev001'
去查看到底bcloud_dev001這個(gè)數(shù)據(jù)庫(kù)占用了多少連接茵乱。 一看竟然有1030個(gè)連接茂洒。
然后我第一猜想會(huì)不會(huì)有連接泄露的情況呢? 然后我參考了這篇文章了解了下 information_schema.PROCESSLIST 這個(gè)表的參數(shù) https://zhuanlan.zhihu.com/p/30743094(具體細(xì)節(jié)不講)
然后我按照表中的TIME 字段進(jìn)行排序
SELECT * FROM information_schema.PROCESSLIST WHERE DB = 'bcloud_test001' ORDER BY TIME desc limit 50
如圖所示,發(fā)現(xiàn)應(yīng)該不是存在泄露以及別的情況似将,因?yàn)閿?shù)據(jù)TIME大值的很少获黔,而且都是在sleep狀態(tài) (sleep狀態(tài)就是等待客戶端向它發(fā)送執(zhí)行語(yǔ)句的狀態(tài))。(如果泄露的話在验,連接沒(méi)有關(guān)閉玷氏,那么連接 會(huì)一直存在下去。而且會(huì)出現(xiàn)大量的長(zhǎng)期存在的聯(lián)接腋舌。當(dāng)然了 這個(gè)要結(jié)合這連接池的配置一起看盏触,初始化連接與當(dāng)前連接個(gè)數(shù)比較)
2、
然后我轉(zhuǎn)手去找springboot中關(guān)于連接池的配置。springboot默認(rèn)的連接池是hikari連接池赞辩,這一塊不細(xì)講雌芽,會(huì)另開一篇文章講解。
找到配置以后發(fā)現(xiàn)還是竟然最小的連接數(shù)的值沒(méi)有設(shè)置辨嗽,最大的設(shè)置到了1024世落。那么問(wèn)題其實(shí)就解決了,
官網(wǎng)中對(duì)于最小值的配置解釋為
??minimumIdle
This property controls the minimum number of idle connections that HikariCP tries to maintain in the pool. If the idle connections dip below this value and total connections in the pool are less than maximumPoolSize, HikariCP will make a best effort to add additional connections quickly and efficiently. However, for maximum performance and responsiveness to spike demands, we recommend not setting this value and instead allowing HikariCP to act as a fixed size connection pool. Default: same as maximumPoolSize
它的默認(rèn)值為 maximumPoolSize 一樣糟需,所以相當(dāng)于初始化的時(shí)候就相當(dāng)于啟動(dòng)了一個(gè)最大值的參數(shù)的連接池屉佳。
后續(xù)自己更改了配置
#指定連接池初始化連接數(shù)
spring.datasource.minimum-idle=20
#指定連接池最大的連接數(shù),包括使用中的和空閑的連接
spring.datasource.maximum-pool-size=500
別的配置我也都反復(fù)看了洲押,我覺(jué)得默認(rèn)值就好武花。官網(wǎng)建議這里設(shè)置一個(gè)固定的連接池最好。但是這里我將最大值設(shè)置成了500杈帐,其實(shí)只是不想背鍋体箕。項(xiàng)目比較大,啥人寫的代碼都有挑童,萬(wàn)一泄露了都是個(gè)問(wèn)題累铅。
多說(shuō)下 wait-timeout
mysql的wait-timeout 這個(gè)配置針對(duì)jdbc連接mysql的情況。如果在mysql中有大量的sleep的連接炮沐,那么設(shè)置這個(gè)參數(shù)就顯得很有必要争群。它的作用是在設(shè)定的時(shí)間內(nèi)關(guān)閉sleep的連接。默認(rèn)值28800(8個(gè)小時(shí))
查看wait-timeout的值
show global variables like 'wait_timeout';
修改wait-timeout的值(將wait_timeout的值修改為30s)
set GLOBAL wait_timeout=30
這樣相當(dāng)于是設(shè)置了全局變量大年,但是如果重啟mysql服務(wù)的話换薄,這個(gè)值又會(huì)被初始化。如果想永久的變動(dòng)此值的話翔试,要在my.cnf的修改此值的大小轻要。