Java 如何调整c3po&;性能方面的问题?

Java 如何调整c3po&;性能方面的问题?,java,mysql,spring,c3p0,spring-jdbc,Java,Mysql,Spring,C3p0,Spring Jdbc,接下来的问题是:为什么com.mchange.v2.resourcepool.BasicResourcePool.waitAvailable()会占用这么多执行时间?如何解决这个问题 现在让我告诉你细节 背景: 我有一个SpringMVCJavaWeb应用程序,它使用SpringJDBC进行数据访问。数据源配置如下: <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method=

接下来的问题是:为什么com.mchange.v2.resourcepool.BasicResourcePool.waitAvailable()会占用这么多执行时间?如何解决这个问题

现在让我告诉你细节

背景: 我有一个SpringMVCJavaWeb应用程序,它使用SpringJDBC进行数据访问。数据源配置如下:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}" />
    <property name="jdbcUrl" value="${jdbc.databaseurl}" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="testConnectionOnCheckout" value="${c3po.testConnectionOnCheckout}" />
    <property name="minPoolSize" value="${c3po.minPoolSize}" />
    <property name="maxPoolSize" value="${c3po.maxPoolSize}" />
    <property name="checkoutTimeout" value="${c3po.checkoutTimeout}" />
    <property name="maxStatementsPerConnection" value="${c3po.maxStatementsPerConnection}" />
</bean>
当前意图: 准备公开的申请。所以我创建了非常简单的JMeter测试计划,它使用500个并发线程一次又一次地简单地打开应用程序的索引页

问题: 我发现性能非常差,大约每秒140个请求,平均请求时间为1700ms,这是完全不可接受的。 请注意,在正常情况下,无负载测试时,该请求大约需要。。6毫秒。 所以我所做的-我运行了jvisualvm,并对其进行了分析。 看起来是com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable()占用了大部分执行时间。

问题: 为什么com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable()会占用这么多执行时间?如何解决这个问题

注1:当然,我正在考虑添加更多缓存逻辑以避免对数据库的调用,但现在我对c3po和mysql优化更感兴趣


注2:我运行的是Windows 7 x64,它不是生产环境(它将是CentOS),但仍然具有顶级i7 intel处理器和SSD磁盘,我希望性能更高=)

请确保定义一个
首选测试查询
,例如
选择1

preferredTestQuery 默认值:null 定义将为所有连接测试执行的查询, 如果默认的ConnectionTester(或 正在使用QueryConnectionTester,或者更好的是FullQueryConnectionTester)。 定义将在数据库中快速执行的preferredTestQuery可能会 大大加快了连接测试的速度。(如果未设置preferredTestQuery,则 默认ConnectionTester对连接的 DatabaseMetaData。根据您的数据库,这可能会执行得更慢 而不是“正常”数据库查询。) ....
因此,有一个基本问题:

您有一个最大连接数为200的池。您有500个并发客户端。如果数据库操作比应用程序正在执行的任何其他操作都慢(这并不少见,因为它是网络IO),那么对于使用数据库连接的每两个客户端线程,将有三个等待(),例如,在waitingavailable()中。如果这是问题的核心,那么它将是池独立的,并且只能通过增加maxPoolSize来解决

但也有一些具体问题。c3p0是一个比大多数“厚”池,尤其是比非常轻的Hikari更厚。在健壮性和可配置性方面(我希望)也有好处,但潜在的性能成本。以下是您可以在c3p0下改进此应用程序性能的一些操作:

1) 设置为高于其默认值3的值,可能为10或20。c3p0将许多维护和测试任务委托给助手线程池。随着您的负载增加,仅使用3个helper线程,这些任务可能会被备份,从而减慢连接签入的完成,从而降低新客户端的可用性

2) 优化您的测试机制。正如geert3所说,除非您使用最新的c3p0[c3p0-0.9.5-pre10]和兼容JDBC4的驱动程序,否则您将退回到非常缓慢的测试。您还将在签出时进行测试,这将减慢每个客户端线程的速度。请参阅以获取一些建议


3) 设置得更大和/或更高。您的池从一个很小的规模开始,并且只需要3个连接就可以成批增长。在这些设置下,需要一些时间才能达到maxPoolSize的完整值200(这仍然不足以在不等待的情况下覆盖您的负载)。在池从小到大的过渡期间,您的500个客户端将花费大量时间等待()。

不要使用C3P0:)。我建议我在这方面有更好的经验。而且你的池边也没有意义,太大的池子会影响你的表现。接下来在不同的硬件和操作系统上运行测试,就像在生产中一样,这是一个无用的练习,因为操作系统可能会产生相当大的影响。谢谢你的建议。我刚试过。好。。。显然,它显示了更好的性能!但是应用程序现在没有响应来自浏览器的请求=)不确定为什么,首先猜测-tomcat已经死了=)您确定它没有响应还是您的测试可能有缺陷?正常的应用程序工作吗?是的,firefox显示的是空页面。我认为这与测试环境以及我在运行tomcat的同一台机器上运行Jmeter这一事实有某种关系。Jmeter说“连接关闭”,也许这和操作系统的限制有关。太神奇了。这只会将性能提高3倍,而且如果将mysql MAX_连接数增加到500,效果会更好。我会将此标记为答案,但下面Steve Waldman的建议也非常有用。
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.databaseurl=jdbc:mysql://localhost:3306/timesheet?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=somepassword
c3po.testConnectionOnCheckout=true
c3po.minPoolSize=5
c3po.maxPoolSize=200
c3po.checkoutTimeout=30000
c3po.maxStatementsPerConnection=50
preferredTestQuery Default: null Defines the query that will be executed for all connection tests, if the default ConnectionTester (or some other implementation of QueryConnectionTester, or better yet FullQueryConnectionTester) is being used. Defining a preferredTestQuery that will execute quickly in your database may dramatically speed up Connection tests. (If no preferredTestQuery is set, the default ConnectionTester executes a getTables() call on the Connection's DatabaseMetaData. Depending on your database, this may execute more slowly than a "normal" database query.) ....