强调 spring boot 服务时消耗的 GCP Postgres 连接(使用 SQL Cloud 代理)

Posted

技术标签:

【中文标题】强调 spring boot 服务时消耗的 GCP Postgres 连接(使用 SQL Cloud 代理)【英文标题】:GCP Postgres connections consumed when stressing spring boot service (using SQL Cloud proxy) 【发布时间】:2021-05-21 00:09:13 【问题描述】:

我正在开发一个 Spring Boot 服务来发布数据并将其保存在 GCP SQL Postgres 数据库中。 问题是,当我通过请求对服务施加压力时,我得到一个关于消耗所有可用连接的 SQL 异常

"FATAL: remaining connection slots are reserved for non-replication superuser connections"

我发现了这个问题,我添加了一个适当的 hikari 配置来限制使用的连接并设置关闭空闲连接的时间限制,这是我的 properties.yml 配置:

 type: com.zaxxer.hikari.HikariDataSource
 hikari:
   initializationFailTimeout: 30000
   idle-timeout: 30000
   minimum-idle: 5
   maximum-pool-size: 15
   connection-timeout: 20000
   max-lifetime: 1000 

当我使用相同的数据库在本地运行该服务时,该服务可以正常工作,但是当我从我的云设置运行它时,它会消耗所有可用的连接,然后得到相同的异常

重要提示!我正在使用 SQL 云代理连接到数据库。

以下是数据库可用连接的屏幕截图:

1- 运行服务之前

2-本地运行服务后

3- 从云端运行服务后

【问题讨论】:

您有多个连接的服务实例,或者您在需要时重新创建数据源(或整个应用程序)。通常这些错误来自后者,但是当涉及到云环境时,您可能会使用自动缩放功能。 @M.Deinum 这是 1 个没有副本的实例,但我开始在 SQL 代理连接中确定问题的范围(至少这是我在一些修复和尝试尝试后的猜测)。会不会是 SQL Proxy 会弄乱 hikari 的配置? 我使用过 Cloud SQL 代理,但从未遇到过此类问题。如果您尝试在不使用 Proxy 的情况下连接 Cloud SQL,是否会出现同样的错误? 【参考方案1】:

在调查了这个问题几天后,我们找到了一个可以缓解问题但没有完全解决的解决方案(最后提到了理想的解决方案)。

如果您想继续使用 SQL 云代理,那么您需要接受您无法完全控制数据库连接配置的事实,因为 SQL 云代理可能会使这些连接保持活动的时间超过您配置的时间它(source)。

为了缓解这个问题,我们使用了来自docker registry 的 SQL Cloud 代理 1.19.2,并且我们使用了这个 hikari 配置:

hikari:
  idle-timeout: 30000 # maximum amount of time (in milliseconds) that a connection is allowed to sit idle in the pool
  minimum-idle: 1 # minimum number of idle connections that HikariCP tries to maintain in the pool, including both idle and in-use connections. If the idle connections dip below this value, HikariCP will make a best effort to restore them quickly and efficiently
  maximum-pool-size: 15 # maximum size that the pool is allowed to reach, including both idle and in-use connections. Basically this value will determine the maximum number of actual connections to the database backend
  connection-timeout: 20000 #maximum number of milliseconds that a client will wait for a connection
  max-lifetime: 20000 # maximum lifetime in milliseconds of a connection in the pool after it is closed.

在这种情况下,正确的解决方案是使用共享 VPC 与您的数据库建立私有连接,您将依靠您的数据库驱动程序来建立这些连接。

【讨论】:

以上是关于强调 spring boot 服务时消耗的 GCP Postgres 连接(使用 SQL Cloud 代理)的主要内容,如果未能解决你的问题,请参考以下文章

将带有 JMS (ActiveMQ) 的 Spring Boot 应用程序迁移到 GCP 的 pub-sub

无法将 Spring Boot 指标发布到 GCP 堆栈驱动程序

Spring boot 和 GCP - 使用 spring-cloud-gcp-starter-sql-postgresql 连接 Cloud SQL 实例尝试 SSL 并且延迟启动

在 GCP PubSub 和 Spring Boot 中捕获发布错误

spring boot 微服务在部署在 ecs aws 的容器中消耗大量内存

使用 vs 代码在 Spring Boot 中设置 GCP 环境变量