Druid連接池
Druid是一個高性能的數據庫連接池,旨在提高數據庫連接性能和管理效率。本文將介紹在Spring框架下使用Druid連接池連接云原生數據倉庫 AnalyticDB MySQL 版(以下簡稱AnalyticDB for MySQL)的配置參數與代碼示例。
注意事項
僅支持Druid 1.1.16以上的版本。
使用Druid連接池連接AnalyticDB for MySQL時,建議配置
<property name="keepAlive" value="true" />
,可以復用連接和避免短連接。AnalyticDB for MySQL前端接入節點使用SLB做負載均衡,客戶端連接前端節點。為了將客戶端請求較為均勻地發送到各個前端節點,建議連接池里有稍多一些連接,且連接保持的時間不宜太長。
根據業務情況合理調整連接池配置,并確保配置生效。您可以在程序中通過
DruidDataSource#getStatData()
和DruidDataSource#dump()
方法定期獲取生效的配置與連接池的信息,并在日志中查看、核對相關配置信息。執行查詢前從連接池獲取連接,執行完查詢后要及時調用
conn.close()
將連接返回到連接池中。再次使用時,請從連接池中獲取新連接,避免長時間使用一個連接導致Druid無法及時檢查到連接失效。復雜網絡情況下,當遇到網關性能達到瓶頸、網絡鏈路長、網絡抖動、重傳率或丟包率高等情形,可能會導致連接中斷。在確保連接池合理配置都生效的情況下,如果仍然有連接中斷的情況,建議業務代碼側通過重試進行優化。
配置Druid連接池
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!--jdbc_url是AnalyticDB MySQL集群的連接地址URL,可以在控制臺的集群信息頁面獲取連接URL。-->
<property name="url" value="${jdbc_url}" />
<!--jdbc_user是AnalyticDB MySQL集群中的用戶賬號:高權限賬號或者普通賬號。-->
<property name="username" value="${jdbc_user}" />
<!--jdbc_password是AnalyticDB MySQL集群中用戶賬號對應的密碼。-->
<property name="password" value="${jdbc_password}" />
<!--配置初始化連接池大小、最小連接數、最大連接數。-->
<property name="initialSize" value="5" />
<property name="minIdle" value="10" />
<property name="maxActive" value="20" />
<!--配置獲取連接等待超時的時間。-->
<property name="maxWait" value="60000" />
<!--配置一個連接在連接池中的最小生存時間、最大生存時間,超過最大生存時間會被移除,單位毫秒。-->
<property name="minEvictableIdleTimeMillis" value="600000" />
<property name="maxEvictableIdleTimeMillis" value="900000" />
<!--配置間隔多久進行一次檢測,檢測需要關閉的空閑連接,單位毫秒。 默認是60s,太長可能會導致無法及時檢測到連接中斷。-->
<property name="timeBetweenEvictionRunsMillis" value="2000" />
<!--配置從連接池獲取連接時,當連接空閑時間大于timeBetweenEvictionRunsMillis時是否檢查連接有效性,true每次都檢查;false不檢查。-->
<property name="testWhileIdle" value="true" />
<!--配置從連接池獲取連接時和向連接池歸還連接時,是否檢查連接有效性。-->
<!--每次獲取或歸還連接都檢測太頻繁,除非特別重要或網絡特別不可靠等情況,建議用testWhileIdle + timeBetweenEvictionRunsMillis代替。-->
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!--配置是否定期探活、探活間隔。-->
<property name="keepAlive" value="true" />
<property name="keepAliveBetweenTimeMillis" value="30000" /> <!--默認120s。-->
<!--配置一個連接最大使用次數,避免長時間使用相同連接造成服務器端負載不均衡。-->
<property name="phyMaxUseCount" value="1000" />
<!--探活、驗證鏈接有效性的查詢,新版本默認使用mysqlPing代替-->
<property name="validationQuery" value="select 1" />
<!--配置監控統計攔截的filters。-->
<property name="filters" value="stat" />
</bean>
生效ValidationQuery
Druid新版本默認使用mysqlPing代替執行ValidationQuery進行探活,如果需要執行ValidationQuery可以進行如下設置:
...
druidDataSource.init();
Properties properties = new Properties();
properties.setProperty("druid.mysql.usePingMethod", "false");
druidDataSource.setConnectProperties(properties);
獲取連接池信息
使用dataSource.dump()
可以獲取連接池和連接的基本信息。
{
CreateTime:"2022-06-01 15:28:10", # 連接池創建時間
ActiveCount:0, # 從連接池取出來在用的連接數
PoolingCount:2, # 在連接池中,未取出去使用的連接數
CreateCount:2, # 創建過的連接數,連接銷毀后重新創建會增加該數量
DestroyCount:0, # 銷毀過的連接數,連接異常或到期銷毀會增加該數量
CloseCount:4, # 調用conn.close()將連接還到連接池的次數
ConnectCount:4, # 調用dataSource.getConnection()獲取連接的次數
Connections:[
{
ID:525571, # 連接ID
ConnectTime:"2022-06-01 15:28:11", # 連接創建時間
UseCount:0, # 連接被獲取使用的次數,所有UseCount加起來等于上面的ConnectCount
LastActiveTime:"2022-06-01 15:28:11" # 連接最后被取出來使用的時間,未使用等于ConnectTime
},
{ID:1263877414, ConnectTime:"2022-06-01 15:28:11", UseCount:4, LastActiveTime:"2022-06-01 15:28:11"}
]
}
獲取連接池生效配置
使用dataSource.getStatData()
可以獲取連接池生效的配置。
{
Identity=85777802,
Name=DataSource-85777802,
DbType=mysql,
DriverClassName=com.mysql.jdbc.Driver,
URL=jdbc:mysql://host:port/db_name,
UserName=haicen,
FilterClassNames=[],
WaitThreadCount=0,
NotEmptyWaitCount=0,
NotEmptyWaitMillis=0,
PoolingCount=2,
PoolingPeak=2,
PoolingPeakTime=Wed Jun 01 16:08:15 CST 2022,
ActiveCount=0,
ActivePeak=1,
ActivePeakTime=Wed Jun 01 16:08:15 CST 2022,
InitialSize=1,
MinIdle=2,
MaxActive=3,
QueryTimeout=0,
TransactionQueryTimeout=0,
LoginTimeout=0,
ValidConnectionCheckerClassName=com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker,
ExceptionSorterClassName=com.alibaba.druid.pool.vendor.MySqlExceptionSorter,
TestOnBorrow=true,
TestOnReturn=true,
TestWhileIdle=true,
DefaultAutoCommit=true,
DefaultReadOnly=null,
DefaultTransactionIsolation=null,
LogicConnectCount=14,
LogicCloseCount=14,
LogicConnectErrorCount=0,
PhysicalConnectCount=6,
PhysicalCloseCount=4,
PhysicalConnectErrorCount=0,
DiscardCount=0,
ExecuteCount=14,
ExecuteUpdateCount=0,
ExecuteQueryCount=14,
ExecuteBatchCount=0,
ErrorCount=0,
CommitCount=0,
RollbackCount=0,
PSCacheAccessCount=0,
PSCacheHitCount=0,
PSCacheMissCount=0,
StartTransactionCount=0,
TransactionHistogram=[
J@6a472554,
ConnectionHoldTimeHistogram=[
J@7ff2a664,
RemoveAbandoned=true,
ClobOpenCount=0,
BlobOpenCount=0,
KeepAliveCheckCount=332,
KeepAlive=true,
FailFast=false,
MaxWait=6000,
MaxWaitThreadCount=-1,
PoolPreparedStatements=false,
MaxPoolPreparedStatementPerConnectionSize=10,
MinEvictableIdleTimeMillis=600000,
MaxEvictableIdleTimeMillis=900000,
LogDifferentThread=true,
RecycleErrorCount=0,
PreparedStatementOpenCount=0,
PreparedStatementClosedCount=0,
UseUnfairLock=false,
InitGlobalVariants=false,
InitVariants=false
}