boneCP是一款關(guān)注高性能的數(shù)據(jù)庫連接池產(chǎn)品 github主頁 。

不過最近作者好像沒有心思更新了,因?yàn)樗l(fā)現(xiàn)了一款更快的連接池產(chǎn)品,但是這不影響我學(xué)習(xí)它。

連接的生存時間

MySQL有一個重要的參數(shù)wait_timeout,用于規(guī)定一個connection最大的idle時間,默認(rèn)是28800秒,即每個connection連續(xù)的sleep狀態(tài)不能超過該值,否則MySQL會自動回收該connection。

連接池的作用是管理連接,任何想要請求數(shù)據(jù)庫連接的行為都和連接池發(fā)生交互,從連接池里申請連接,使用完成后將連接交還給連接池。

在一個比較空閑的系統(tǒng)上,連接可能長時間的處于sleep狀態(tài),那么一旦達(dá)到了MySQL wait_timeout的規(guī)定時間,MySQL就要回收連接,這時連接池如果仍然認(rèn)為該connection可用,待應(yīng)用向連接池請求時,就會將不存在的connection資源交給應(yīng)用,這樣就會報錯。

因此連接池需要一套機(jī)制保證每一個connection在連接池生存期內(nèi)是始終可用的。

我推測應(yīng)該有兩種機(jī)制:定期檢測和申請時檢測。

boneCP采用定期檢測機(jī)制,即每隔一個時間間隔就會檢查其管理的連接處于sleep狀態(tài)的時間,如果超過了設(shè)定的值,則會將此connection重建。

boneCP中有兩個很重要的參數(shù):idleConnectionTestPeriodInSeconds和idleMaxAgeInSeconds,分別是連接探測時間閾值和連接最大空閑時間,默認(rèn)值為4小時和1小時。

boneCP會啟動三個線程來進(jìn)行定期任務(wù):

this.keepAliveScheduler =  Executors.newScheduledThreadPool(this.config.getPartitionCount(), new CustomThreadFactory("BoneCP-keep-alive-scheduler"+suffix, true));this.maxAliveScheduler =  Executors.newScheduledThreadPool(this.config.getPartitionCount(), new CustomThreadFactory("BoneCP-max-alive-scheduler"+suffix, true));this.connectionsScheduler =  Executors.newFixedThreadPool(this.config.getPartitionCount(), new CustomThreadFactory("BoneCP-pool-watch-thread"+suffix, true));

其中keepAliveScheduler用來每隔一段時間檢查connection的sleep狀態(tài)時間是否達(dá)到了idleMaxAgeInSeconds或者是否已經(jīng)失效,如果是,則會將連接kill掉,主要的邏輯見ConnectionTesterThread.java。

需要注意的是,在默認(rèn)的配置下,該檢查的調(diào)度是這樣定義的:

this.keepAliveScheduler.scheduleAtFixedRate(connectionTester,delayInSeconds,&