我在 Heroku 上运行 Web 服务并使用 New Relic 监控其性能。我使用的是 MySQL 和 Hibernate。我的非默认 c3p0 设置如下
hibernate.c3p0.maxStatementsPerConnection, 5
hibernate.c3p0.maxPoolSize, 35
hibernate.c3p0.minPoolSize, 5
hibernate.c3p0.initialPoolSize, 10
hibernate.c3p0.acquireIncrement, 10
对我的 Web 服务的每个请求都至少访问数据库几次。在运行 10 分钟约 200 个请求/分钟的负载测试后,我发现大部分时间花在了
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();
}
}
}
所以我确定所有 session 都已关闭,这应该转化为连接关闭。为什么当我增加最大连接数时等待时间会变长?似乎性能从 hibernate.c3p0.maxPoolSize, 25
提高到 hibernate.c3p0.maxPoolSize, 30
,但在 hibernate.c3p0.maxPoolSize, 35
。我的值(value)观离我远吗?
谢谢!
最佳答案
作为猜测,我会尝试增加 numHelperThreads .你的负担很重;也许 c3p0 的管理线程正在备份。 (如果你转储堆栈跟踪或使用 JMX 来监视 c3p0,你应该能够看到这一点。如果你有足够的辅助线程,它们通常应该空闲(),等待()ing。如果它们正在备份,你会看到它们大多是 Activity 的和可运行的,通过 JMX,您将看到任务排队。)
辅助线程不足与您观察到的 maxPoolSize 性能先好后坏一致。最初你得到了你想要的,准备好了更多的连接,但随后辅助线程无法跟上,添加更多的连接只会让事情变得更糟。
根据您的设置,辅助线程不应有太多工作要做,除非 maxStatementsPerConnection 太小。如果您的应用程序有超过 5 个频繁运行的 PreparedStatements,那么您最终将通过 Statements 搅动并将 helper Threads 与 Statement close() 任务捆绑在一起。您可以尝试将此值调大。它应该大约(四舍五入)您的应用程序持续使用的不同 PreparedStatements 的数量。 (您可以忽略单个或很少使用的 PreparedStatements,例如在设置或清理中涉及。)同样,监视辅助线程正在做什么会给您关于这是否是问题的信息。 (您会看到备份的 Statement close() 任务。)
所以,可以尝试:增加 numHelperThreads,增加 maxStatementsPerConnection (或将其设置为零,以完全关闭语句缓存。)
祝你好运!
关于java - c3p0 getConnection 在连接数增加时挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18435432/