有一個線上環境使用的是c3p0數據庫,為外部提供接口服務。最近訪問壓力增大后台tomcat的日志里面頻繁出現
com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@1c83354 -- timeout at awaitAvailable()
的異常信息
在網上搜索了半天找到兩種最多的方法:
1.修改checkoutTimeout的值,這個值我現在已經設定是5000了也就是5秒超時,如果再大就沒意義了,一個接口5秒還沒響應是非常不正常的。
2.增加acquireIncrement的值,這個值感覺也不靠譜,只是增大了每次獲取的數量,如果根本就獲取不到連接就無意義。
無奈只好優化程序,加大連接池的maxPoolSize和minPoolSize的值。
但是就算把 maxPoolSize 的值設置的比tomcat的最大線程的值大,過不了一會還是出現那個問題。我就奇怪了就算每個請求永久占用一個連接也夠用了,怎么還會出現獲取連接超時的問題。
然后繼續在晚上搜數據庫連接池發現了bonecp。
換上這個后果然問題解決,日志里面再沒出現獲取連接超時的問題。
看來c3p0在大並發的情況下還真的是不容樂觀啊。
順便說下項目的並發情況,單台tomcat 最大maxThreads的值設為400,每次啟動后tomcat的日志中都會出現線程超過最大線程的信息。 也就是峰值並發數 > 400 。
- <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
- <property name="driverClass" value="com.mysql.jdbc.Driver" />
- <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/data?useUnicode=true&characterEncoding=utf8" />
- <property name="username" value="root"/>
- <property name="password" value="123456"/>
- <property name="idleConnectionTestPeriodInMinutes" value="240"/>
- <property name="idleMaxAgeInMinutes" value="60"/>
- <property name="maxConnectionsPerPartition" value="250"/>
- <property name="minConnectionsPerPartition" value="40"/>
- <property name="partitionCount" value="2"/>
- <property name="acquireIncrement" value="10"/>
- <property name="statementsCacheSize" value="0"/>
- <property name="releaseHelperThreads" value="5"/>
- <property name="connectionTimeoutInMs" value="5000"/>
- </bean>
以上是我的配置文件,初始值設置為2x40=80 也就是第一次會創建80個連接。 所以項目啟動后第一次請求會比較慢,大概5-10秒才會有響應。