[英]c3p0 getConnection Hangs as Number of Connections are Increased
我在Heroku上運行Web服務,並使用New Relic監視其性能。我在頂部使用Hibernate的MySQL。我的非默認c3p0設置如下
hibernate.c3p0.maxStatementsPerConnection, 5
hibernate.c3p0.maxPoolSize, 35
hibernate.c3p0.minPoolSize, 5
hibernate.c3p0.initialPoolSize, 10
hibernate.c3p0.acquireIncrement, 10
對我的Web服務的每個單個請求都會至少兩次訪問數據庫。 在以每分鍾200個請求/分鍾的速度運行了10分鍾的負載測試后,我發現大部分時間都花在了
com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection
我猜它正在等待連接池中的連接? 有趣的是隨着我的增加
hibernate.c3p0.maxPoolSize, 40
性能變差了(在相同的getConnection
調用中等待時間更長。在測試中,我看到c3p0
連接的最大數目確實在MySQL服務器上打開(在MySQL端設置的最大連接數為300
,絕對沒有用盡)。
我所有的數據庫函數都使用相同的格式
public void executeTransaction( Session session, IGenericQuery<T> query, T entity )
{
Transaction tx = null;
try
{
tx = session.beginTransaction();
query.execute( session, entity );
tx.commit();
}
catch ( RuntimeException e )
{
try
{
tx.rollback();
}
catch ( RuntimeException e2 )
{
}
throw e;
}
finally
{
if ( session != null )
{
session.close();
}
}
}
因此,我確定所有會話均已關閉,這應轉化為連接關閉。 為什么增加最大連接數會增加等待時間? 似乎性能從hibernate.c3p0.maxPoolSize, 25
的hibernate.c3p0.maxPoolSize, 30
增加到hibernate.c3p0.maxPoolSize, 30
,但是在hibernate.c3p0.maxPoolSize, 35
之后下降。 我的價值觀遠嗎?
謝謝!
作為一個猜測,我會嘗試增加numHelperThreads 。 你負擔很重; 也許c3p0的管理線程正在備份。 (如果您轉儲堆棧跟蹤記錄或使用JMX監視c3p0,您應該能夠看到此消息。如果您有足夠的幫助程序線程,則它們通常應該處於idle(),wait()ing。如果要備份它們,則將看到它們大部分處於活動狀態且可運行,並且通過JMX,您將看到排隊的任務。)
輔助線程的不足與您通過maxPoolSize觀察到的更好然后更差的性能一致。 最初,您會獲得所需的東西,可以准備更多的連接,但是之后輔助線程無法跟上,添加更多的連接只會使情況變得更糟。
給定您的設置,輔助線程應該沒有太多工作要做,除非maxStatementsPerConnection太小。 如果您的應用程序具有5個以上經常運行的PreparedStatement,那么您最終將遍歷Statements並使用Statement close()任務捆綁幫助程序線程。 您可以嘗試將該值增大。 它應該大約(四舍五入)應用程序持續使用的不同PreparedStatement的數量。 (您可以忽略單個或很少使用的PreparedStatement,例如,涉及設置或清除。)再次,監視要使用的幫助程序線程將為您提供有關此問題的信息。 (您會看到備份的Statement close()任務。)
因此,可以嘗試:增加numHelperThreads,增加maxStatementsPerConnection (或將其設置為零,以完全關閉語句緩存)。
祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.