我试图在我们的服务中导致一些随机的,间歇性的“冻结”,在丢弃了几个问题之后,我们为我们的应用程序启用了c3p0调试级别日志记录,我们认为它看起来像c3p0配置问题。我们使用“Oracle Database 11g企业版版本11.2.0.3.0 - 64位生产”作为我们的数据库。
日志摘录显示两行是服务调用的一部分。两条线之间没有3秒的活动,我无法将其归因于任何特定的东西。
12 Apr 2013 02:25:42,386 [DEBUG] (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#8) com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool: Test of PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@1507a7] on CHECKIN has SUCCEEDED.
12 Apr 2013 02:25:45,443 [DEBUG] com.mchange.v2.c3p0.stmt.GooGooStatementCache: checkinStatement(): com.mchange.v2.c3p0.stmt.PerConnectionMaxOnlyStatementCache stats -- total size: 85; checked out: 0; num connections: 5; num keys: 85
c3p0配置如下。
acquireIncrement = 2;
acquireRetryAttempts = 0; # keep retrying forever
acquireRetryDelay = 10000; # 10 secs.
checkoutTimeout = 1000; # 1 secs.
idleConnectionTestPeriod = 60; # 1 min.
maxConnectionAge = 1800; # 30 mins.
maxIdleTime = 1800; # 30 mins.
maxIdleTimeExcessConnections = 120;
maxPoolSize = 30;
maxStatementsPerConnection = 25;
minPoolSize = 30;
initialPoolSize = 30;
numHelperThreads = 16; # asynchronous threads
preferredTestQuery = "SELECT 1 FROM dual";
testConnectionOnCheckin = true;
我想知道是否存在导致冻结的配置问题?另外,我想知道通过设置minPoolSize = maxPoolSize是否会对性能产生任何影响(负面)。我无法找到有回答的类似问题/问题。我并不担心应用程序的启动时间,但是当连接达到“年龄”时会发生什么?我正在尝试理解处理陈旧连接时的c3p0行为。
为了了解负载,我们每分钟可获得300个服务电话。 CPU /内存使用都在合理的水平,没有特别感兴趣。
任何见解将不胜感激。 谢谢! -Ameya
答案 0 :(得分:0)
1)minPoolSize = maxPoolSize = initialPoolSize应该没有问题,虽然它不是我测试过的配置!
2)大部分你的配置看起来都不错!一些狡辩:
acquireIncrement为2意味着,在一些平静期后的负载上升期间,大约50%的客户端将面临一些等待连接获取的延迟。我会使acquireIncrement更大,3到5;
acquireRetryDelay = 10000表示如果任何类型的随机故障导致采集尝试失败,则获取新连接时的任何类型的随机故障都将导致客户端在空池上等待(等待10秒)等待10秒。 10000是一个很高的设置。
您没有观察到明确的APPARENT DEADLOCK消息,但是您正在使用对它们非常负责的配置,即使用Oracle +语句缓存。某些Oracle驱动程序存在一个问题,即在其父连接正在使用(例如,用于测试)时尝试关闭()缓存的语句会导致冻结,最终强制池清除并重新创建其帮助程序线程。你已经给了自己许多帮助线程,这可能有助于避免这个问题,但是由于线程池中的线程堵塞,你可能会遇到性能损害。 c3p0-0.9.2有一个配置参数,如果设置,i)小心避免在父连接正在使用时关闭缓存的PreparedStatements,ii)并使用专用的线程关闭这些语句。我建议你试一试。如果你还没有,请升级到c3p0-0.9.2.1并设置
c3p0.statementCacheNumDeferredCloseThreads=1
(你不太可能只需要关闭()语句就可以使用多个线程,但如果你愿意,可以将其设置为更大的值。请参阅here。)