我们有一个使用hibernate作为ORM工具的api,我们使用c3p0作为连接池处理程序。我们在负载下没有问题。但是,当api处于非活动状态一天左右时,我们正在用尽“无法获取连接”异常。因此,如果周末没有人使用api,我们会在周一早上收到连接错误。
引起:java.sql.SQLException:客户端尝试签出连接已超时。
我们使用mysql作为数据库。在我的研究中,我知道mySQL在8小时左右后连接失效。连接池可能会发出与客户端的陈旧连接,从而导致客户端的连接超时异常。
目前,我们没有在C3Po中配置任何连接测试。可以说,如果我在池中将它们提供给客户端之前使用IdleTestPeriod来测试连接。那么如果我的所有连接在某个时间点都未通过测试会发生什么?是否会从池中删除这些失败的连接,并再次生成新的活动连接?
目前,这是我们正在使用的c3p0设置。这个问题可能有其他原因吗?
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${----}"/>
<property name="jdbcUrl" value="${----}"/>
<property name="user" value="${----}"/>
<property name="password" value="${------}"/>
<property name="minPoolSize" value="5"/>
<property name="acquireIncrement" value="5" />
<property name="maxPoolSize" value="125" />
<property name="maxStatements" value="10" />
<property name="maxIdleTime" value="180" />
<property name="maxIdleTimeExcessConnections" value="30" />
<property name="checkoutTimeout" value="3000" />
<property name="preferredTestQuery" value="SELECT 1" />
</bean>
答案 0 :(得分:10)
所以你的checkoutTimeout设置为3秒(3000毫秒)。这就是你所看到的例外情况。客户端只允许等待三秒钟从池中检出连接;如果三秒钟还不够,他们会看到你的例外。
问题是,为什么客户需要这么长时间才能获得连接?通常检查一个连接是一个非常快速的操作。但如果检出所有连接,则客户端必须等待(缓慢)从数据库中获取连接。
您已将池配置为非常积极地剔除连接。 minPoolSize = 5以上的任何数量的连接如果空闲超过maxIdleTimeExcessConnections = 30秒,将被销毁。然而,您的池配置为大规模突发:maxPoolSize = 125。假设您的应用程序安静了一段时间,然后从客户端获取一连串请求。池将快速耗尽连接并开始获取,以winsIncrement = 5的突发。但是如果突然有25个客户端并且池只有5个连接,那么第25个客户端在获取连接之前可能会超时。
你可以做很多事情。这些调整是可分的,您可以根据需要混合或匹配。
剔除空闲的“多余”连接不那么积极,因此通常,您的池有一定的容量来服务突发请求。您可能完全丢弃maxIdleTimeExcessConnections,并且在maxIdleTime = 180秒不使用后让Connections慢慢消失。 (下行?在不活动期间更长的资源占用时间更长。)
将minPoolSize设置为更高的值,以便池不太可能看到连接太少的活动突发。 (下行?更大的永久性资源足迹。)
从配置中删除checkoutTimeout。 c3p0的默认设置是允许客户端无限期地等待连接。 (下行?也许您希望客户快速报告失败而不是等待可能的成功。)
我不认为您所观察到的问题与连接测试或MySQL超时本身有很大关系,但这并不意味着您不应该处理这些问题。我将遵循nobeh关于MySQL重新连接问题的建议。 (我不是一个很大的MySQL用户。)你应该考虑实现连接测试。你有一个preferredTestQuery,所以测试应该相当快。我通常的选择是使用testConnectionOnCheckin和idleConnectionTestPeriod。见http://www.mchange.com/projects/c3p0/#configuring_connection_testing
祝你好运!答案 1 :(得分:1)
在MySQL Java Connector的高可用性和群集部分中,查看属性;具体为autoReconnect
和autoReconnetForPools
。
使用JDBC连接URL中的属性。
在使用MySQL,Hibernate和C3P0之前,他们帮助了我。希望这会有所帮助。