Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java c3p0 getConnection随着连接数的增加而挂起_Java_Mysql_Hibernate_Heroku_C3p0 - Fatal编程技术网

Java c3p0 getConnection随着连接数的增加而挂起

Java c3p0 getConnection随着连接数的增加而挂起,java,mysql,hibernate,heroku,c3p0,Java,Mysql,Hibernate,Heroku,C3p0,我在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, 1

我在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服务的每一个请求都会至少命中数据库几次。在运行了大约200个请求/分钟的负载测试10分钟后,我发现大部分时间都花在了数据库上

com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection
我猜它在等待连接池中的连接?有趣的部分是随着我的增加

hibernate.c3p0.maxPoolSize, 40
性能更差(在相同的
getConnection
调用中等待时间更长。在测试期间,我可以看到MySQL服务器上的最大
c3p0
连接数确实是打开的(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();
        }
    }
}
public void executeTransaction(会话会话,IGenericQuery查询,T实体)
{
事务tx=null;
尝试
{
tx=session.beginTransaction();
执行(会话、实体);
tx.commit();
}
捕获(运行时异常e)
{
尝试
{
tx.回滚();
}
捕获(运行时异常e2)
{
}
投掷e;
}
最后
{
if(会话!=null)
{
session.close();
}
}
}
因此,我确定所有会话都已关闭,这应转化为连接关闭。为什么随着我增加最大连接数,等待时间会更长?性能似乎从
hibernate.c3p0.maxPoolSize,25
增加到
hibernate.c3p0.maxPoolSize,30
,但在
hibernate.c3p0.maxPoolSize>之后会下降,35
。我的价值观是否相去甚远


谢谢!

作为猜测,我会尝试增加。您的负载很重;可能c3p0的管理线程正在备份。(如果转储堆栈跟踪或使用JMX监视c3p0,您应该能够看到这一点。如果您有足够的帮助线程,它们通常应该是空闲的(),wait()如果它们正在备份,您将看到它们大部分处于活动状态且可运行,而通过JMX,您将看到任务排队。)

辅助线程的不足与您观察到的maxPoolSize的性能先好后坏是一致的。最初您得到了想要的,更多的连接准备就绪,但是辅助线程无法跟上,添加更多的连接只会让事情变得更糟

根据您的设置,除非maxStatementsPerConnection太小,否则助手线程不应该有太多的工作要做。如果您的应用程序有5个以上频繁运行的PreparedStatement,那么您将结束对语句的混乱,并使用语句close()捆绑助手线程任务。您可以尝试将此值增大。它应该大约是(四舍五入)应用程序持续使用的不同PreparedStatements的数量。(您可以忽略单个或很少使用的PreparedStatements,例如在安装或清理过程中。)同样,监视助手线程的活动将为您提供有关这是否是问题的信息(您将看到备份语句close()任务)

所以,要尝试的是:增加numHelperThreads,增加(或将其设置为零,以完全关闭语句缓存)


祝你好运!

谢谢你的帮助。不同命名的HQL查询的数量大约是40。但是对于我的负载测试,我最多只使用10个。我尝试将
MaxStatementSpercConnection的数量增加到20个,运行相同的负载场景,但仍然有很多相同的错误。我查看了我的数据库端,CPU使用率为我有一种感觉,我只是碰到了数据库的瓶颈(它是一个Amazon RDS中型实例)。本质上,我使用2-4台服务器,每个服务器都具有上述设置,以相同的方式访问数据库。无论我如何调整服务器,最多24个线程/线程池,最多30个线程/线程池(2到4台服务器正在运行),数据库只是在100%的CPU级别上运行。我甚至没有接近数据库上允许的最大连接数,24*2=48,35*4=140<300。使用MySQL Admin,我可以看到几乎所有的连接在再次使用之前都有最少的睡眠时间。这让我相信我已经达到了数据库的极限。因此,如果您的数据库饱和,那么我们当然会解释性能问题,但这并不能解释为什么要在getConnection()上花费大量时间,特别是因为您似乎没有要求c3p0测试连接(这可能会将c3p0的性能与dbms的性能结合起来)。我觉得还是很奇怪。如果db饱和了,那么等待连接到db的所有未完成线程不会在
com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection()中花费很多时间吗
等待连接被释放?如果客户端正在等待池获取新连接,则会这样做。但一旦池达到maxPoolSize,就没有新的连接获取可等待(除非某些连接无效,在您的配置中,这只会延迟发生,因为您没有显式测试)。