【发布时间】:2018-11-16 05:40:42
【问题描述】:
我一直在我的 Spring Boot 应用程序上使用 HikariCP,我开始使用 JMeter 进行一些负载测试。
我注意到我第一次运行测试时运行良好,每个请求大约需要 30 毫秒。
但是每次我针对同一个应用程序实例再次运行我的测试时,响应时间会变得更糟,直到它冻结并且我得到很多
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30019ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:583)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:186)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:145)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at sun.reflect.GeneratedMethodAccessor501.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at net.bull.javamelody.JdbcWrapper$3.invoke(JdbcWrapper.java:805)
at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:286)
at com.sun.proxy.$Proxy102.getConnection(Unknown Source)
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:246)
... 108 common frames omitted
我什至将应用程序搁置了一天并再次尝试,但测试显示性能下降和相同的错误。
只有当我关闭应用程序时,它才能再次运行我的测试,但只有一次负载(1200 多个请求)。
当我开发测试时,我使用 H2 数据库运行本地应用程序,直到我将应用程序部署到运行 postgresql 的服务器上后才发现性能下降。
所以为了消除这个变量,我让 JMeter 在我的本地 H2 应用程序上运行,并且性能下降。
这是我在本地应用程序(H2 数据库)上运行的测试场景,默认 HikariCP 轮询大小 (10),使用 10 个线程。在应用程序停止响应之前,我设法运行了 25000 多个请求。
我绘制了请求:
此外,测试包括对 Spring Boot @RestController 的请求。
我的控制器调用了一个在开始时具有 @Transactional 的服务(我调用了一些需要事务存在的遗留 API,因此我立即打开它)。
假设我的测试并行请求此端点 10 次。假设我的代码可能还有其他点用@Transactional 注释。 10 个投票大小就足够了吗?
此外,任何投票规模是否都足够,尽管性能很差,还是“正常”出现这种投票只是太忙而“锁定”的情况?
我也尝试将投票大小增加到 50,但问题仍然存在。它接近之前测试的 25000 个请求(轮询大小为 10),并且如前所述失败。
【问题讨论】:
-
您检查过没有连接泄漏吗?
-
应用程序重启立即消除问题?
-
问题可能(几乎可以肯定)不在于池。检查数据库上发生了什么。你能启用慢查询日志吗?是否发生死锁?
-
@user7294900 我不知道如何检查它。我确实启用了 HikariCP leakDetectionThreshold,但它所做的只是在应用程序已经显示降级时记录“检测到可能的泄漏”。
-
@MikhailKholodkov 确实如此。
标签: java multithreading performance spring-boot hikaricp