spring - 连接时从 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.property
的hikari
连接池中添加了额外的行,如下所示,
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 个连接。
混乱
- 这是因为任何数据库默认设置吗?
- 还是因为连接数据库引擎时出现 Tomcat 问题?
即使我尝试pgbouncer
在我的数据库节点中使用连接池工具。然后我也遇到了同样的问题。
如果这是由于数据库默认设置或配置造成的,我该如何覆盖它?
解决方案
微服务架构是一种将应用程序分解为多个独立服务的架构,这些服务易于理解、开发、测试并且容易出错。
现在根据上面的定义,每个独立的服务都应该有自己独立的独立数据库。但如果需要,这些服务可以相互通信以获取数据。
每个服务都应在其特定数据库中具有选定的实体。
如果您为所有这些独立服务提供了一个公共数据库,那么您就违反了微服务架构的规则。
在这种情况下,数据冗余的风险很高。
可能在您的情况下,服务包含重复版本的数据并可能耗尽整个连接池。
更好的方法是为单独的独立服务提供单独的数据库(仅包含特定于该服务的实体)。
澄清:
解释如上。
为所有 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
按照此链接阅读如何配置:
https://blogs.ashrithgn.com/multiple-data-source-in-spring-boot-using-spring-boot-data-starter/
https://www.ru-rocker.com/2018/01/28/configure-multiple-data-source-spring-boot/
或者您可能需要使用 Hikari-CP 进行 Hibernate Multi-tenancy。
推荐阅读
- python - 如何有效地从 Redshift 中删除数据?
- neo4j - 在损坏之前,“(node)-[r:player*]->()”查询工作正常,但在导入损坏的修复数据后就不行了
- ios - xcode - 资产目录 - 图像类型 - 相同的比例 - 不同的分辨率
- python-3.x - 使用 MinMaxScaler 缩放数据导致不可散列的类型错误
- python - 用黑色高亮选中的项目,用绿色高亮已经选中的项目
- flutter - 从颤动的页面返回时如何刷新上一个屏幕/页面列表?
- drop-down-menu - 使用javascript在html中选择第一个选择框后如何打开第二个选择框的列表?
- php - 运行url并从结果url-PHP中获取参数值
- android - 我的用例可以使用什么本地搜索引擎?
- python - 有什么方法可以将 z-index 应用于 python-docx 单词报告中的图像,或者以其他方式在 python-docx 报告中添加背景/水印图像?