根據綜合性能,可靠性,穩定性,擴展性,易用性等因素替換成最優的數據庫連接池。
Druid:druid-1.0.29
數據庫 Mysql.5.6.17
替換目標:替換掉C3P0,用druid來替換
替換原因:
1、性能方面 hikariCP>druid>tomcat-jdbc>dbcp>c3p0 。hikariCP的高性能得益於最大限度的避免鎖競爭。
2、druid功能最爲全面,sql攔截等功能,統計數據較爲全面,具有良好的擴展性。
3、綜合性能,擴展性等方面,可考慮使用druid或者hikariCP連接池,比較方便對jdbc接口進行監控跟蹤等。
4、可開啓prepareStatement緩存,對性能會有大概20%的提升。
- psCache是connection私有的,所以不存在線程競爭的問題,開啓pscache不會存在競爭的性能損耗。
- psCache的key爲prepare執行的sql和catalog等,value對應的爲prepareStatement對象。開啓緩存主要是減少了解析sql的開銷。
5、3p0歷史悠久,代碼及其複雜,不利於維護。並且存在deadlock的潛在風險。
6、Druid可以打印SQL,慢查詢方面的日誌
Druid 參數
配置參數 | 缺省值 | 遊戲服設置的值 | 參數說明 |
initialSize | 0 | 4 | 初始化連接數量 |
minIdle | 0 | 4 | 最小空閒連接數 |
maxActive | 8 | 8 | 最大併發連接數 |
maxWait | -1L | 60000 | 獲取連接時最大等待時間,單位毫秒。配置了maxWait之後, 缺省啓用公平鎖,併發效率會有所下降, 如果需要可以通過配置useUnfairLock屬性爲true使用非公平鎖。 |
timeBetweenEvictionRunsMillis | 60000 | 60000 | 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 Destroy線程會檢測連接的間隔時間 |
minEvictableIdleTimeMillis | 1800000 | 1800000 | 配置一個連接在池中最小生存的時間,單位是毫秒 |
validationQuery | null | select 1 | 用來檢測連接是否有效的sql,要求是一個查詢語句 |
testOnBorrow | FALSE | FALSE | 申請連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能。 |
testOnReturn | FALSE | FALSE | 歸還連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能 |
testWhileIdle | TRUE | TRUE | 建議配置爲true,不影響性能,並且保證安全性。 申請連接的時候檢測,如果 空閒時間大於 timeBetweenEvictionRunsMillis, 執行validationQuery檢測連接是否有效。 |
poolPreparedStatements | FALSE | TRUE | false 是否緩存preparedStatement,也就是PSCache。 PSCache對支持遊標的數據庫性能提升巨大,比如說oracle。 在mysql5.5以下的版本中沒有PSCache功能,建議關閉掉。 5.5及以上版本有PSCache,建議開啓。 |
maxPoolPreparedStatementPerConnectionSize | 10 | 100 | 要啓用PSCache,必須配置大於0,當大於0時, poolPreparedStatements自動觸發修改爲true。 單個connnection獨享一個statement cache,也就是說maxOpenPreparedStatements是針對單個connection鏈接的 |
運行原理:
數據庫連接池在初始化的時候會創建initialSize個連接,當有數據庫操作時,會從池中取出一個連接。如果當前池中正在使用的連接數等於maxActive,則會等待一段時間,等待其他操作釋放掉某一個連接,如果這個等待時間超過了maxWait,則會報錯;如果當前正在使用的連接數沒有達到maxActive,則判斷當前是否空閒連接,如果有則直接使用空閒連接,如果沒有則新建立一個連接。在連接使用完畢後,不是將其物理連接關閉,而是將其放入池中等待其他操作複用。 同時連接池內部有機制判斷,如果當前的總的連接數少於miniIdle,則會建立新的空閒連接,以保證連接數得到miniIdle。如果當前連接池中某個連接在空閒了timeBetweenEvictionRunsMillis時間後仍然沒有使用,則被物理性的關閉掉。有些數據庫連接的時候有超時限制(mysql連接在8小時後斷開),或者由於網絡中斷等原因,連接池的連接會出現失效的情況,這時候設置一個testWhileIdle參數爲true,可以保證連接池內部定時檢測連接的可用性,不可用的連接會被拋棄或者重建,最大情況的保證從連接池中得到的Connection對象是可用的。當然,爲了保證絕對的可用性,你也可以使用testOnBorrow爲true(即在獲取Connection對象時檢測其可用性),不過這樣會影響性能。
如果要進行SQL監控,可以加入以下代碼:
- Log4j2Filter log4j2 = new Log4j2Filter();
- log4j2.setResultSetLogEnabled(false);
- log4j2.setStatementSqlPrettyFormat(false);
- log4j2.setStatementExecutableSqlLogEnable(true);
-
- log4j2.setDataSourceLogEnabled(false);
- log4j2.setConnectionLogEnabled(false);
- log4j2.setStatementLogEnabled(false);
- log4j2.setResultSetLogEnabled(false);
- ret.setProxyFilters(Arrays.asList(log4j2));
閒置檢測,創建連接,廢棄連接清理由這三線程管理
Daemon Thread [Abandoned connection cleanup thread]
Daemon Thread [Druid-ConnectionPool-Create-1184124073]
Daemon Thread [Druid-ConnectionPool-Destroy-1184124073]
參考文章:數據庫連接池性能比對(hikari druid c3p0 dbcp jdbc)
對於sql的監控可以使用druid的web監控界面監控sql的執行效率:
配置如下
spring.datasource.druid.driverClassName=com.mysql.jdbc.Driver
#開發庫
spring.datasource.druid.url=jdbc:mysql://xxxx/xx?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
spring.datasource.druid.username=xx
spring.datasource.druid.password=xxx
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=60000
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 1
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=true
spring.datasource.druid.testOnReturn=false
# 打開PSCache,並且指定每個連接上PSCache的大小
spring.datasource.druid.poolPreparedStatements=true
# 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用於防火牆
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.druid.filters=stat,wall,log4j2
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
spring.datasource.druid.connectionProperties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
# 配置DruidStatFilter
spring.datasource.druid.web-stat-filter.enabled=false
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
# 配置DruidStatViewServlet
spring.datasource.druid.stat-view-servlet.enabled=false
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
# 禁用HTML頁面上的“Reset All”功能
spring.datasource.druid.stat-view-servlet.reset-enable=false
# 登錄名
spring.datasource.druid.stat-view-servlet.login-username=admin
# 登錄密碼
spring.datasource.druid.stat-view-servlet.login-password=123456
項目啓動後可以訪問http://127.0.0.1:8085/druid/wall.html
登錄監控界面
如下: