java - c3p0 导致应用程序偶尔超时

标签 java c3p0

我的应用程序每分钟都会被一个 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" />

最佳答案

c3p0 的后台线程始终存在;它们在线程池中运行。您已将该池的大小设置为 10 个线程 (c3p0.numHelperThreads)。如果您检查堆栈转储,在您的配置下您将看到 c3p0 任务(例如 CullExpired)运行得相当频繁。这些频率与导致资源过期的配置设置处于同一数量级。在您的情况下, maxIdleTime 为 60 秒,因此剔除任务可能每 20 秒左右运行一次。 c3p0 的管理任务经过精心设计,不会在 IO 期间持有锁,并且通常是轻量级的,并且尽可能不与其他工作竞争。因此,如果是这些管理任务导致您挂起,就会发生一些奇怪的事情。但这里很难区分原因和巧合:c3p0 的辅助线程始终存在,并且管理任务经常运行。

maxIdleTime 是对您的问题的一种可能的解释。您使用的配置不是很好。每分钟一个客户端连接对于 c3p0 来说是一个非常小的负载,但您的 minPoolSize 为 10 个连接。因此,c3p0 获取 10 个连接,将它们保留大约一分钟,然后过期并重新获取所有连接,这是大量的同时开销。 80 秒的idleConnectionTestPeriod 是没有帮助的:空闲连接永远不会被测试,因为它们将在空闲60 秒后、测试期结束之前过期。我还将 acquireIncrement 降回默认值 3。

我会尝试更好的配置,看看是否可以解决问题。鉴于您描述的负载,我将 minPoolSize 保留为默认值 3,并将 numHelperThreads 设置为 3。作为第一遍,我将 maxIdleTime 设置为默认值 0,但将 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系列现在已经相当稳定,值得使用。

希望这会有所帮助!

关于java - c3p0 导致应用程序偶尔超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13215532/

相关文章:

hibernate - c3p0 创建的连接数多于配置中指定的连接数

java - 如何在没有jar文件的情况下在命令行中编译和运行Netbeans java项目?

java - 子实体引用如何在使用 OSIV 方法(在 View 中打开 session )的应用程序中返回 LazyInitializationException?

web-applications - c3p0 中的内存泄漏 - java.lang.NoClassDefFoundError : com/mchange/v2/resourcepool/BasicResourcePool

mysql - 由 :java. lang.NoClassDefRoundError:com/mchange/v2/ser/indirector 引起

java - 如何将 FlexyPool 与 HikariCPFactory 一起使用?

java - 使用分数表对 java 列表进行排序

java - Maven 命令 "mvn clean jetty:run"和其他 mvn 命令在 Eclipse 中不起作用

java - 如何在另一个方法中调用类内的构造函数

mysql - 在客户端测试服务器故障转移时如何正确使用loadBalanceBlacklistTimeout