每分钟都会通过一个http请求查询我的应用程序。 当c3p0运行CullExpired和其他后台线程时,应用程序暂时超时并变得无响应。此问题是随机发生的,并且不经常发生。应用程序超时的所有实例,我看到c3p0后台线程正在运行,试图进行清理或驱逐空闲连接。这种情况非常随机发生,日志中没有其他例外情况。一段时间后,应用程序会自动恢复并恢复处理。有没有人遇到过这样的问题。
c3p0 version is <version>0.9.1.2</version>
hibernate version is <version>3.3.2.GA</version>
我的c3p0配置是:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="#{['app.jdbc.driverClassName']}"
p:jdbcUrl="#{['app.jdbc.url']}"
p:user="#{['app.jdbc.username']}"
p:password="#{['app.jdbc.password']}"
p:acquireIncrement="5"
p:idleConnectionTestPeriod="80"
p:maxAdministrativeTaskTime="600"
p:numHelperThreads="10"
p:maxIdleTime="60"
p:maxPoolSize="20"
p:maxStatements="30"
p:minPoolSize="10" />
答案 0 :(得分:2)
c3p0的后台线程总是存在;它们在线程池中运行。你已经将该池的大小设置为10个线程(c3p0.numHelperThreads)。如果你检查堆栈转储,在你的配置下你会看到像CullExpired这样的c3p0任务经常运行。这些频率与资源到期的配置设置处于同一数量级。在您的情况下,maxIdleTime是60秒,因此剔除任务可能每20秒左右运行一次。 c3p0的管理任务经过精心设计,不会在IO期间保持锁定,并且通常要轻量级,并且尽可能不与其他工作竞争。所以,如果这些管理员任务导致你的挂起,那就会发生奇怪的事情。但是很难说出原因和巧合之间的区别:c3p0的辅助线程总是存在,管理任务经常运行。
maxIdleTime是您问题的一种可能解释。您使用的配置不是很好。每分钟一个客户端连接是c3p0的超小负载,但您有一个10个连接的minPoolSize。因此,c3p0抓取10个连接,保持它们大约一分钟,然后到期并重新获取所有这些,这是很多同时的开销。您的idleConnectionTestPeriod为80秒是无益的:空闲连接将永远不会被测试,因为它们将在测试时间段过去之前的60秒空闲后过期。我还将acquireIncrement放回默认值3。
我会尝试更好的配置,看看是否能解决问题。鉴于您描述的负载,我将minPoolSize保留为默认值3,并将numHelperThreads设置为3.作为第一遍,我将maxIdleTime设置为其默认值零,但将testConnectionOnCheckout设置为true。这是最简单,最可靠的连接测试形式,但它确定了客户端可见的性能成本。要最小化该成本,您应该设置preferredTestQuery而不是依赖于慢速默认连接测试。通常“SELECT 1”可以工作,但它可能取决于您的数据库/ JDBC驱动程序。如果事情看起来不错,你可能会更大胆地尝试稍微更高效,稍微不那么健壮的连接测试策略:将idleConnectionTestPeriod设置为相对较小的值(例如30),并将testConnectionOnCheckin设置为true(并将testConnectionOnCheckout设置为其默认值false) 。见[http://www.mchange.com/projects/c3p0/#configuring_connection_testing]
此外,我现在关闭语句缓存(将maxStatements设置为0),并在事情稳定后再将其打开以测试它是否可以提高应用程序的性能。 [这是一个if - 见http://www.mchange.com/projects/c3p0/#known_shortcomings]
我还建议您更新到最新版本的c3p0 [c3p0-0.9.2-pre5]。在0.9.2中,连接获取的重量更轻一些,部分问题可能与您每1分钟刷新和重新获取周期有关。总的来说,我认为0.9.2-pre系列现在非常稳定,值得使用。
我希望这有帮助!