一、Spring Boot 2.+默認連接池HikariCP
如果是Spring Boot2.+,那麼默認的連接池就是Hikaricp,不需要再另外導入包和配置,怎麼證明?啓動項目,可以看到控制檯
啓動信息HikariPool
啓動信息HikariDataSource
我們在控制檯看到了
HikariPool-1 - Starting...
HikariPool-1 - Start completed
Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
說明Spring Boot 2.+默認使用的就是連接池HikariCP
二、調整連接池參數
HikariCP連接池提供了默認值,如果有需要也可以在配置文件裏進行調整參數
spring:
########-spring datasource-########
datasource:
#賬號配置
url: jdbc:mysql://127.0.0.1:3306/retail_db?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: ENC(5raHicqGiQ1nEXKO+R9ykYwJUrD/+nbx)
password: ENC(1NiRLG1lUkzLSg3uerUwU0bIRCDYiZnX)
driver-class-name: com.mysql.cj.jdbc.Driver
#hikari數據庫連接池
hikari:
pool-name: Retail_HikariCP
minimum-idle: 5 #最小空閒連接數量
idle-timeout: 180000 #空閒連接存活最大時間,默認600000(10分鐘)
maximum-pool-size: 10 #連接池最大連接數,默認是10
auto-commit: true #此屬性控制從池返回的連接的默認自動提交行爲,默認值:true
max-lifetime: 1800000 #此屬性控制池中連接的最長生命週期,值0表示無限生命週期,默認1800000即30分鐘
connection-timeout: 30000 #數據庫連接超時時間,默認30秒,即30000
connection-test-query: SELECT 1
type: com.zaxxer.hikari.HikariDataSource
三、HikariCP連接池速度快於其他連接池的原因
-
相比於普通連接池,在ConnectionProxy中使用ArrayList來存儲Statement對象,HikariCP改用FatList來存儲對象,而其中的區別是,ArrayList在每次執行get(Index)方法時,都需要對List的範圍進行檢查,而FastList不需要,在能確保範圍的合法性的情況下,可以省去範圍檢查的開銷。
-
另外在Java代碼中,很多關於Connection的操作,都是在使用完之後直接關閉連接,以前都是從頭到尾遍歷,來關閉對應的Connection,而HikariCP則是從尾部對Connection集合進行掃描,整體上來說,從尾部開始的性能更好一些。
-
內部使用一個無鎖的集合來存儲,並對其中的切換操作做了優化。
-
從字節碼指令的角度去優化,連接池使用
PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnNames))語句來建立statements,resultset等的實例,將其翻譯成字節碼指令後,會有如下的指令,0: getstatic和15: invokevirtual #69。將上述的方法改爲使用 ProxyFactory.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnNames)),後,就不在需要0: getstatic指令,並且使用了12: invokestatic #67代替了15: invokevirtual #69,前者invokestatic 更容易被JIT優化。另外從堆棧的角度來說,堆棧大小也從原來的5變成了4。
四、HiKariCP和Druid對比
我們所熟知的C3P0,DBCP,Druid, HiKariCP爲我們所常用的數據庫連接池,其中C3P0已經很久沒有更新了。DBCP更新速度很慢,基本處於不活躍狀態,而Druid和HikariCP處於活躍狀態的更新中,這就是我們說的二代產品了。
HiKariCP
- 字節碼精簡 :優化代碼,直到編譯後的字節碼最少,這樣,CPU緩存可以加載更多的程序代碼;
- 優化代理和攔截器 :減少代碼,例如HikariCP的Statement proxy只有100行代碼,只有BoneCP的十分之一;
- 自定義數組類型(FastStatementList)代替ArrayList :避免每次get()調用都要進行range check,避免調用remove()時的從頭到尾的掃描;
- 自定義集合類型(ConcurrentBag :提高併發讀寫的效率;
- 其他針對BoneCP缺陷的優化。
Druid
- Druid提供性能卓越的連接池功能外,還集成了SQL監控,黑名單攔截等功能,
- 強大的監控特性,通過Druid提供的監控功能,可以清楚知道連接池和SQL的工作情況。
- 監控SQL的執行時間、ResultSet持有時間、返回行數、更新行數、錯誤次數、錯誤堆棧信息;
- SQL執行的耗時區間分佈。什麼是耗時區間分佈呢?比如說,某個SQL執行了1000次,其中01毫秒區間50次,110毫秒800次,10100毫秒100次,1001000毫秒30次,1~10秒15次,10秒以上5次。通過耗時區間分佈,能夠非常清楚知道SQL的執行耗時情況;
- 監控連接池的物理連接創建和銷燬次數、邏輯連接的申請和關閉次數、非空等待次數、PSCache命中率等。
- 方便擴展。Druid提供了Filter-Chain模式的擴展API,可以自己編寫Filter攔截JDBC中的任何方法,可以在上面做任何事情,比如說性能監控、SQL審計、用戶名密碼加密、日誌等等。
總的來說:
1、HiKariCP性能比Druid高
2、HiKariCP是Spring Boot 2+官方支持,和Spring Boot兼容性更好
3、Druid的優勢是監控完善,擴展性更好(但攔截過多也會增加框架複雜度以及框架性能)
具體選HiKariCP或Druid視團隊具體需求而定,提供Druid的用法 : Spring Boot 使用Druid連接池整合Mybatis-Plus連接Mysql數據庫
參考文章