当前位置: 首页 > 知识库问答 >
问题:

最大连接池是否也限制到数据库的最大连接数?

景俊拔
2023-03-14

我正在使用hikari cp和spring boot应用程序,它有超过1000个并发用户。我已经设置了最大池大小-

spring.datasource.hikari.maximum-pool-size=300

当我使用

show processlist;

它显示的最大值为300,等于池大小。它永远不会增加超过最大池。这是故意的吗?我认为池大小意味着保持连接,以便在将来需要数据库请求时可以重用连接,但在需要时可以进行更多连接。

另外,当我删除max pool配置时,我会立即得到-

HikariPool-0-连接不可用,请求在30000ms后超时。

如何解决这个问题。提前谢谢。

共有1个答案

景仲渊
2023-03-14

是的,这是有意的。引用留档:

此属性控制池允许达到的最大大小,包括空闲连接和正在使用的连接。基本上,该值将确定到数据库后端的实际连接的最大数量。合理的值最好由您的执行环境决定。当池达到此大小且没有空闲连接可用时,对getConnection()的调用将在超时前阻塞最多connectionTimeout毫秒。请阅读有关池大小的信息。默认值:10

因此,基本上,当所有300个连接都在使用中,并且您正试图建立301st连接时,Hikari不会创建新的连接(因为maximumPoolSize是绝对最大值),而是会等待(默认情况下为30秒),直到连接再次可用。

这也解释了为什么会出现您提到的异常,因为默认值(在未配置maximumPoolSize时)是10个连接,您可能会立即到达。

为了解决这个问题,你必须找出为什么这些连接被阻塞超过30秒。即使在有1000个并发用户的情况下,如果您的查询需要几毫秒或最多几秒钟,也应该没有问题。

如果调用非常复杂的查询需要很长时间,那么有几种可能性。第一个是增加池的大小。但不建议这样做,因为计算最大池大小的建议公式为:

connections = ((core_count * 2) + effective_spindle_count)

引用关于池大小的文章:

一个多年来在许多基准测试中保持良好的公式是,为了实现最佳吞吐量,活动连接的数量应该接近((core_count*2)effective_spindle_count)。核心计数不应包括HT线程,即使启用了超线程。如果活动数据集被完全缓存,有效主轴数为零,并且随着缓存命中率的下降而接近实际主轴数。...到目前为止,还没有任何关于这个公式在固态硬盘上的效果的分析

正如同一篇文章中所描述的,这意味着一个4核服务器和一个硬盘应该只有大约10个连接。即使你可能有更多的核心,我假设你没有足够的核心来保证你正在建立的300个连接,更不用说进一步增加了。

另一种可能是增加连接超时。如前所述,当所有连接都在使用时,默认情况下会等待30秒,即连接超时。

您可以增加此值,以便应用程序在超时前等待更长时间。如果复杂查询需要20秒,并且连接池中有300和1000个并发用户,则理论上应将连接超时至少配置为20*1000/300=67秒。

但是请注意,这意味着您的应用程序可能需要很长时间才能向用户显示响应。如果您有67秒的连接超时,并且在复杂查询完成之前还有20秒,那么您的用户可能需要等待一分半钟。

如前所述,您的主要目标是找出查询花费如此长时间的原因。连接池为300,连接超时为30秒,并发用户为1000,这意味着您的查询至少需要9秒才能完成,这是很多。

尝试通过以下方式缩短执行时间:

  • 添加适当的索引
  • 正确地编写查询
  • 改进数据库硬件(磁盘、核心、网络等)
  • 通过引入分页来限制正在处理的记录数量
  • 分工。看看是否可以将查询拆分为较小的查询,从而生成中间结果,然后在另一个查询中使用,依此类推。只要您不在事务中工作,就可以在事务之间释放连接,从而允许您以牺牲某些性能为代价为多个用户提供服务
  • 使用缓存
  • 预先计算结果:如果您正在进行一些资源密集型计算,您可以尝试在应用程序不经常使用的时刻(例如,在夜间)预先计算结果,并将这些结果存储在可以轻松查询的其他表中

 类似资料:
  • 嘿,我正在使用Glassfish开源v4,我遇到了一个奇怪的问题。 我在管理控制台中定义了到Oracle 11g的JDBC连接池,并设置了: 初始和最小池大小:500 最大游泳池大小:1000 池大小调整数量::750 我已经为这个连接池创建了一个特定的用户。然而,有时当我检查数据库中打开的连接时,我发现有1000多个连接(我看到的最大连接数是1440个) 当发生这种情况时,任何查询尝试都会失败,

  • 在OkHttp中,我找不到设置硬最大连接池大小的方法。从留档https://square.github.io/okhttp/3.x/okhttp/okhttp3/ConnectionPool.html很明显,您可以设置最大空闲连接,但不能设置整体最大值。这意味着在高负载下,它可以增长超过任何限制。 有没有办法最大化池?如果没有,为什么没有?

  • 问题陈述 我们在嵌入式模式下使用H2已有一段时间了。它上面配置了一个连接池。以下是当前池配置: H2配置: *跳过用户名和密码属性。 我们已经通过记录池属性验证了上述配置的有效性。 这个设置的问题是,我们观察到连接池经常(尽管是间歇性的)耗尽,一旦连接池达到最大限制,它就开始为一些查询抛出以下异常。 SqlExceptionHelper.log异常(SqlExceptionHelper.java:

  • 问题内容: 目前,我们正在使用带有8gb RAM的4个cpu窗口框,并在同一框上安装了MySQL5.x。我们正在为应用程序使用Weblogic应用程序服务器。我们的应用程序目标是200个并发用户(显然不是同一模块/屏幕)。那么,我们应该在连接池中配置的最佳连接数是多少(最小和最大数)(我们正在使用weblogic AS的连接池机制)? 问题答案: 这个问题有一个非常简单的答案: 连接池中的连接数应

  • 问题内容: JPA /hibernate查询中允许的联接数是否有限制? 由于Hibernate 不会自动加入,因此我必须在JPA / Hibernate查询中明确指定加入。例如,一个人有一个地址,一个地址有一个状态。以下查询检索地址和状态已满的人员: 随着我不断添加联接,最终(在左联接12-13之后)达到了Hibernate生成无效SQL的限制: 我确实将Hibernate的方言设置为数据库实现M

  • 因为Websockets构建在TCP之上,所以我的理解是,除非端口在连接之间共享,否则您将受到64K端口限制的约束。但我也看到过使用Gretty进行512K连接的报告。所以我不知道。