調優資料庫連接池
建立與DBMS的JDBC串連過程可能是相當緩慢的。如果您的應用程式需要反覆開啟和關閉資料庫連接,這可以成為一個顯著的效能問題。在JBoss AS中資料來源的串連池提供了一種有效解決該問題的方法。
要強調的是,當用戶端關閉一個資料來源的串連時,該串連返回到池中,這樣可用於其它的用戶端,因此,串連本身並沒有關閉。開啟和關閉池管理的串連的成本可以以納秒來衡量,所以它對效能的影響無關緊要。
在下面的例子中,我們將強調在第三章講解的資料來源配置,使用串連池配置來提供企業服務:
<datasource jndi-name="MySqlDS" pool-name="MySqlDS_Pool" enabled="true" jta="true" use-java-context="true" use-ccm="true"> <connection-url> jdbc:mysql://localhost:3306/MyDB </connection-url> <driver>mysql</driver> <pool> <min-pool-size>10</min-pool-size> <max-pool-size>30</max-pool-size> <prefill>true</prefill> </pool> <timeout> <blocking-timeout-millis>30000</blocking-timeout-millis> <idle-timeout-minutes>5</idle-timeout-minutes> </timeout> </datasource> |
在這裡,我們配置了10個串連的初始池的容量,最大可以增長到30。正如你可以從下面的MySQL管理主控台中看到的,當你設定pre-fill元素為true,則應用伺服器試圖在啟動時預先建立串連。這可能會產生效能損失,特別是如果串連的擷取很昂貴的時候。
如果應用伺服器因為串連池的串連都在使用,而不能獲得更多的串連,那麼它會一直等待直到阻塞逾時(blocking-timeout-millis),這時會拋出一個異常給用戶端。
同時,如果串連空閑超過了參數idle-timeout-minute設定的時間,則他們被迫返回到池中。
調整池大小
要確定合適的池大小,你需要監視資料庫連接的使用,這可以通過幾種方式來完成。使用命令列,您可以監視資料來源的運行時效能。下面是一個將在第4章講述的應用程式的樣本:
[standalone@localhost:9999 /]/subsystem=datasources/data-source="java:/MySqlDS":read-resource(include-runtime=true) { "outcome" => "success", "result" => { "ActiveCount" => "10", "AvailableCount" => "29", "AverageBlockingTime" => "0", "AverageCreationTime" => "56", "CreatedCount" => "10", "DestroyedCount" => "0", "MaxCreationTime" => "320", "MaxUsedCount" => "5", "MaxWaitCount" => "0", "MaxWaitTime" => "1", . . . . } } |
此命令的輸出有點長,然而最有趣的屬性是輸出的開頭部分:尤其是ActiveCount,它顯示了當前活動的串連數,MaxUsedCount是由應用程式使用的串連的峰值數。
注意:如果您設定了預初始化串連池,前面的部分,這些串連將一直處於活躍狀態。這可能造成誤解,導致你認為他們一直很忙。
如果您無法使用CLI或只是你要好好利用你的DBA認證,有一些有效可選方法:首先,最顯而易見的是監視資料庫會話。下表列出了一些有用的命令,這些命令可以用來跟蹤在不同資料庫上的活動的串連:
資料庫 |
命令/ 表 |
Oracle |
查詢V$SESSION視圖 |
MySQL |
使用命令SHOW FULL PROCESSLIST |
Postgre-SQL |
查詢PG_STAT_ACTIVITY表 |
另一種選擇是使用像P6Spy的工具,它充當JDBC代理的驅動。 (我部落格關於它的文章在這裡))。
一旦你找到應用程式使用串連的峰值,設定至少高出25-30%作為最大值。不要擔心設定的最大值過高,因為如果你不需要這麼多的串連,池將自動收縮,前提是你已經設定了idle-timeout-minutes。
另一方面,伺服器日誌在協助你檢查串連池運行問題時,仍然是一個非常寶貴手段。例如,如果你在你的伺服器日誌中看到這個異常,這說明你需要你去看看串連池是否正常:
21:57:57,781 ERROR [stderr] (http-executor-threads - 7) Caused by: javax.resource.ResourceException: IJ000655: No managed connections available within configured blocking timeout (30000 [ms]) 21:57:57,782 ERROR [stderr] (http-executor-threads - 7) at org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreArrayListManagedConnectionPool.getConnection |