yml 配置文章來源地址http://www.zghlxwxcb.cn/news/detail-745276.html
- minimum-idle:10
該參數(shù)限制數(shù)據(jù)庫連接池保持?jǐn)?shù)據(jù)連接的最小數(shù)量,如下當(dāng)我們啟動(dòng)服務(wù)時(shí),不做任何請(qǐng)求,服務(wù)就會(huì)默認(rèn)建立10個(gè)數(shù)據(jù)庫連接。等到有需求的時(shí)候就可以及時(shí)使用。
我們啟動(dòng)服務(wù)不做任何請(qǐng)求可以看到數(shù)據(jù)庫與服務(wù)的連接數(shù)就是10. 且狀態(tài)都為sleep.
這里記錄一個(gè)問題,假設(shè)有這樣一個(gè)分布式微服務(wù)服務(wù)(campus-sign-up-service), 該服務(wù)hikari配置如第一張圖,如果該服務(wù)有2實(shí)例,那么這兩個(gè)實(shí)例的最小連接數(shù)分別是10,還是公用配置總共為10呢?答案是分別為10,每個(gè)實(shí)例都會(huì)單獨(dú)按照上面的配置去建立連接。
這里我們啟動(dòng)兩個(gè)實(shí)例在去查看一下數(shù)據(jù)庫中的連接數(shù)量,可以發(fā)現(xiàn)實(shí)例數(shù)量變?yōu)?*10=20. - maximum-pool-size:40
該配置意為在同一時(shí)間應(yīng)用向數(shù)據(jù)庫連接池請(qǐng)求的數(shù)連接超過最小連接數(shù)時(shí),將根據(jù)需求擴(kuò)大數(shù)據(jù)庫連接數(shù),但是該鏈接數(shù)的上線是maximum-pool-size的值,如這里的40。當(dāng)請(qǐng)求超過最大連接數(shù)時(shí),進(jìn)入等待隊(duì)列,直到有空閑的連接。
如下我們創(chuàng)建80個(gè)線程去執(zhí)行業(yè)務(wù)邏輯計(jì)算和數(shù)據(jù)庫請(qǐng)求。public AddCourseEntity studentBookCourse(AddCourseEntity addCourseEntity) { Date startTime=StudentUtil.getDateTime(); System.out.println("Start Time:" + startTime); for(int i=0;i<=80;i++) { Thread thread= new Thread(()->{ studentHandler.longTransactionTest(addCourseEntity); }); thread.start(); } return addCourseEntity; }
為了保證請(qǐng)求數(shù)據(jù)庫的線程數(shù)在同一時(shí)間一定大于40,我們?cè)谄渲幸粋€(gè)事務(wù)里面再睡60s。(當(dāng)然真實(shí)開發(fā)過程中,要避免將耗時(shí)的業(yè)務(wù)邏輯處理加入事務(wù)中,長(zhǎng)事務(wù)會(huì)長(zhǎng)時(shí)間占用其申請(qǐng)到的數(shù)據(jù)庫連接線程,造成極大浪費(fèi)。當(dāng)大量請(qǐng)求進(jìn)來時(shí),數(shù)據(jù)庫鏈接被消耗完遲遲不能釋放,就會(huì)阻塞其他請(qǐng)求或是導(dǎo)致其他請(qǐng)求因申請(qǐng)不到數(shù)據(jù)庫鏈接池中的連接線程而超時(shí)失敗。如下代碼,開始時(shí)線程休眠,但是只要運(yùn)行進(jìn)入@Transactional 注入的方法,就已經(jīng)占用數(shù)據(jù)庫資源了,不論這個(gè)時(shí)候是否開始了數(shù)據(jù)庫的相關(guān)操作。最極端的情況,如下我們只保留休眠代碼,和數(shù)據(jù)庫操作相關(guān)的代碼都刪除,這個(gè)事務(wù)方法一樣的從方法開始就會(huì)占用數(shù)據(jù)庫連接池里面的一個(gè)線程)@Transactional public void saveInfoAndTableA(AddCourseEntity addCourseEntity) throws InterruptedException { Thread.sleep(60*1000); TableA tableA = new TableA(); StudentUtil.assembleTableA(addCourseEntity, tableA); tableARepository.save(tableA); addCourseEntity.setTableAId(tableA.getId()); }
經(jīng)過測(cè)試我們可以統(tǒng)計(jì)到數(shù)據(jù)庫的連接已經(jīng)達(dá)到最大鏈接數(shù)40。
總共有80個(gè)線程在請(qǐng)求,剩余的40個(gè)請(qǐng)求線程就被迫處于等待狀態(tài)。
? - connection-timeout: 20000 鏈接上一個(gè)測(cè)試結(jié)果接續(xù)說明,當(dāng)剩余的40個(gè)請(qǐng)求線程等待數(shù)據(jù)庫連接池中釋放線程時(shí)間超過20s,請(qǐng)求線程就開始報(bào)錯(cuò)了
? - max-lifetime: 50000?
idle-timeout: 10000
如上兩個(gè)參數(shù)我要連著一起總結(jié),官方網(wǎng)站對(duì)這兩個(gè)參數(shù)的解釋分別如下:
max-lifetime: This property controls the maximum lifetime of a connection in the pool. An in-use connection will never be retired, only when it is closed will it then be removed. On a connection-by-connection basis, minor negative attenuation is applied to avoid mass-extinction in the pool. We strongly recommend setting this value, and it should be several seconds shorter than any database or infrastructure imposed connection time limit. A value of 0 indicates no maximum lifetime (infinite lifetime), subject of course to the idleTimeout setting. The minimum allowed value is 30000ms (30 seconds). Default: 1800000 (30 minutes)
idle-timeout: This property controls the maximum amount of time that za connection is allowed to sit idle in the pool. This setting only applies when minimumIdle is defined to be less than maximumPoolSize. Idle connections will not be retired once the pool reaches minimumIdle connections. Whether a connection is retired as idle or not is subject to a maximum variation of +30 seconds, and average variation of +15 seconds. A connection will never be retired as idle before this timeout. A value of 0 means that idle connections are never removed from the pool. The minimum allowed value is 10000ms (10 seconds). Default: 600000 (10 minutes)
max-lifetime: 最小允許值30s 默認(rèn)值:30min
This property controls the maximum lifetime of a connection in the pool: 這句話的意思是如果當(dāng)前鏈接處于空閑狀態(tài),且存活時(shí)間超過設(shè)定的最大存活時(shí)間,就會(huì)關(guān)閉這個(gè)鏈接,并根據(jù)設(shè)置判定是否再啟動(dòng)新的連接。
idle-timeout: 最小允許值10s 默認(rèn)值:10min
測(cè)試總結(jié):對(duì)于這兩邊我不再展示測(cè)試過程,而直接寫測(cè)試結(jié)果(如下結(jié)果都是經(jīng)過反復(fù)測(cè)試)。
case 1:配置max-lifetime:50s 而idle-timeout:1s
顯然idle-timeout配置錯(cuò)誤小于了其最小允許值,框架將自動(dòng)使用默認(rèn)值10min。當(dāng)我們同時(shí)啟動(dòng)40個(gè)線程請(qǐng)求,每個(gè)需要執(zhí)行1min,顯然單個(gè)線程執(zhí)行時(shí)間已經(jīng)超過了max-lifetime設(shè)置的50s,這個(gè)時(shí)候這40個(gè)線程可以成功執(zhí)行,在40個(gè)請(qǐng)求線程都執(zhí)行完成后不再發(fā)起新的請(qǐng)求,數(shù)據(jù)的這40個(gè)鏈接什么時(shí)候釋放到最小鏈接數(shù)10呢? 答案是10min后。
case2:配置max-lifetime:50s 而idle-timeout:1s
同樣是case1中的條件,但是我們將測(cè)試用例中的單個(gè)線程需要執(zhí)行1min,修改為20s,并且在40個(gè)請(qǐng)求線程都執(zhí)行完成后不再發(fā)起新的請(qǐng)求,那么多余的線程多久后釋放呢?答案是30s(50s-20s)后,數(shù)據(jù)庫連接數(shù)由40降到10.
case3:配置max-lifetime:50s 而idle-timeout:1min
如果有40個(gè)請(qǐng)求線程,每個(gè)如case1中執(zhí)行1min, 由于執(zhí)行時(shí)間已經(jīng)超過了max-lifetime的設(shè)置,這個(gè)時(shí)候如果后續(xù)不來新的請(qǐng)求,那么多余的線程就按照idle-timeout設(shè)置的合理時(shí)間去清理多余線程,也就是1min。 總結(jié):max-lifetime是根據(jù)請(qǐng)求線程自身情況計(jì)算清理時(shí)間,重請(qǐng)求線程自身去設(shè)定的釋放限制,idle-timeout是對(duì)所有請(qǐng)求線程進(jìn)行的統(tǒng)一限制。 每個(gè)請(qǐng)求都要遵循這兩個(gè)原則去關(guān)閉。由兩個(gè)原則計(jì)算出來的最近時(shí)間去判斷是否釋放請(qǐng)求所占有的數(shù)據(jù)個(gè)鏈接。
這里記錄一個(gè)額外的問題,minimum-idle: 閑時(shí)大小的設(shè)置是否會(huì)消耗我們服務(wù)的線程。
1. minimum-idle:100
2. minimum-idle:5
從而可以得出結(jié)論,數(shù)據(jù)的連接池?cái)?shù)量,應(yīng)該是由hikri的統(tǒng)一管理的,并不會(huì)因?yàn)殚e時(shí)線程數(shù)量的設(shè)置變大,而而外的消耗我們服務(wù)的線程資源。
文章來源:http://www.zghlxwxcb.cn/news/detail-745276.html
到了這里,關(guān)于springboot中Hikari連接池常用參數(shù)含義(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!