首页 > 解决方案 > 连接时从 Spring Boot 项目到 PostgreSQL 数据库的连接问题

问题描述

我正在使用 Spring MVC、Spring Boot 和 PostgreSQL 开发一个面向微服务的多租户应用程序。在我的服务域中,我有 30 个不同数量的 Spring Boot 项目连接到同一个数据库。

问题

当我并行启动超过 11 个 Spring Boot 项目时,我无法从数据库中检索数据。我只收到空白的 JSON 响应。但是如果我开始的项目少于 11 个,那么到那时,我就能得到微服务的结果。当我从第 12 次服务开始时遇到问题。

故障排除和我的调查

根据阅读,我做了如下一些改动,

我设置了 PostgreSQL 配置文件,max_connections = 100并且shared_buffers = 128MB.

但这并没有解决我的问题。并且还在我application.propertyhikari连接池中添加了额外的行,如下所示,

spring.datasource.hikari.minimumIdle=3
spring.datasource.hikari.maximum-pool-size=3

即使这也不能解决我的问题。尽管如此,我一次最多只能启动 12 个 Spring Boot 项目。

在 pom.xml 上添加了以下内容,

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-jpa</artifactId>
 <exclusions>
    <exclusion>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>tomcat-jdbc</artifactId>
  <version>9.0.10</version>
</dependency>

application.property 更新了以下内容,

spring.datasource.tomcat.initial-size=15
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.max-active=20
spring.datasource.tomcat.max-idle=20
spring.datasource.tomcat.min-idle=5
spring.datasource.tomcat.default-auto-commit=true

更新

正如我上面提到的,我总共有 100 个最大连接。当我启动第一个微服务并通过查询(以下查询)监视数据库连接时,我得到了 10 个连接。

select max_conn,used,res_for_super,max_conn-used-res_for_super res_for_normal 
from 
 (select count(*) used from pg_stat_activity) t1,
 (select setting::int res_for_super from pg_settings where 
  name=$$superuser_reserved_connections$$) t2,
 (select setting::int max_conn from pg_settings where 
 name=$$max_connections$$) t3

活动截图 - 当我只启动 1 个微服务时,我得到了这样的结果,

在此处输入图像描述

活动截图二:

在此处输入图像描述

所以在这里,对于每个微服务启动,10 个数据库连接在后端数据库级别启动。所以如果我启动超过 30 个微服务应用程序,它会去超过 300 个连接。

混乱

  1. 这是因为任何数据库默认设置吗?
  2. 还是因为连接数据库引擎时出现 Tomcat 问题?

即使我尝试pgbouncer在我的数据库节点中使用连接池工具。然后我也遇到了同样的问题。

如果这是由于数据库默认设置或配置造成的,我该如何覆盖它?

标签: springpostgresqlspring-boot

解决方案


微服务架构是一种将应用程序分解为多个独立服务的架构,这些服务易于理解、开发、测试并且容易出错。

现在根据上面的定义,每个独立的服务都应该有自己独立的独立数据库。但如果需要,这些服务可以相互通信以获取数据。

每个服务都应在其特定数据库中具有选定的实体。

如果您为所有这些独立服务提供了一个公共数据库,那么您就违反了微服务架构的规则。

在这种情况下,数据冗余的风险很高。

可能在您的情况下,服务包含重复版本的数据并可能耗尽整个连接池。

更好的方法是为单独的独立服务提供单独的数据库(仅包含特定于该服务的实体)。

澄清:

  1. 解释如上。

  2. 为所有 Spring Boot 模块/项目维护单独的数据源 hikari 连接池。

例如:假设您有两个模块/项目的两个数据源 -

在 application.properties 中。

## datasource for first service/module ##
datasource1.url=jdbc:postgresql://localhost:3306/service1
datasource1.username=service1
datasource1.password=password1
datasource1.driver-class-name=org.postgresql.Driver
datasource1.initial-size=15
datasource1.max-wait=20000
datasource1.max-active=20
datasource1.max-idle=20
datasource1.min-idle=5
datasource1.default-auto-commit=true

## datasource for second service/module ##
datasource2.url=jdbc:postgresql://localhost:3306/service2
datasource2.username=service2
datasource2.password=password2
datasource2.driver-class-name=org.postgresql.Driver
datasource2.initial-size=15
datasource2.max-wait=20000
datasource2.max-active=20
datasource2.max-idle=20
datasource2.min-idle=5
datasource2.default-auto-commit=true

按照此链接阅读如何配置:

  1. https://blogs.ashrithgn.com/multiple-data-source-in-spring-boot-using-spring-boot-data-starter/

  2. https://www.ru-rocker.com/2018/01/28/configure-multiple-data-source-spring-boot/

或者您可能需要使用 Hikari-CP 进行 Hibernate Multi-tenancy。


推荐阅读