如何让 Spring Boot 自动重新连接到 PostgreSQL?

Posted

技术标签:

【中文标题】如何让 Spring Boot 自动重新连接到 PostgreSQL?【英文标题】:How do I get Spring Boot to automatically reconnect to PostgreSQL? 【发布时间】:2017-01-26 13:51:31 【问题描述】:

我正在运行连接到 PostgreSQL 数据库的 Spring Boot。如果在数据库之后启动 Spring Boot,我已经验证了数据已写入数据库。

spring.datasource.url = jdbc:postgresql://localhost/dbname
spring.datasource.username = user
spring.datasource.password = secret
spring.datasource.driver-class-name = org.postgresql.Driver
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1

当数据库在开发中发生变化时,我会遇到异常: PreparedStatementCallback; SQL []; This connection has been closed.; nested exception is org.postgresql.util.PSQLException: This connection has been closed.

注意,当异常发生时,可以再次访问数据库;我认为问题在于连接已过时,因为它最初连接的数据库端点由于重新启动而不再可用。重新启动 Spring Boot 即可解决此问题。

如何配置 Spring Boot 以重新连接到 PostgreSQL,这样我就不需要重新启动它了?

我已尝试关注Spring Boot JPA - configuring auto reconnect 和How to reconnect database if the connection closed in spring jpa? 中的答案。我不确定 PostgreSQL 的行为是否与 mysql 不同。我对Spring Boot documentation 的阅读没有帮助;我不太了解所描述的组件,无法理解我应该查看哪些文档。

【问题讨论】:

您使用的是哪个连接池?如果您不使用它,您可能想尝试切换到 Hikari。我过去曾在tomcat-jdbc 看到过类似的问题,这是目前的默认连接池。 您已经对借用进行了测试,但您可能还想设置空闲和空闲超时时的检查。这样会定期检查连接,如果无效,则将其从池中删除。 @AndyWilkinson 我想我正在使用 tomcat-jdbc 因为我的 pom 包含 spring-boot-starter-jdbc。 【参考方案1】:

Spring boot 应该配置为自动重新连接,问题是它不知道断开的连接。

由于您已经在借用和验证查询上使用测试,只需尝试减少验证间隔,以便每次都执行。

spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.validation-query=SELECT 1
spring.datasource.tomcat.validation-interval=0

Tomcat jdbc connection pooltestOnBorrow:

(boolean) 指示对象在从池中借用之前是否经过验证。如果对象验证失败,它将从池中删除,我们将尝试借用另一个。注意 - 要使真值生效,validationQuery 或 validatorClassName 参数必须设置为非空字符串。 为了进行更有效的验证,请参阅validationInterval。默认值为假

但请注意validationInterval:

(long) 避免过度验证,最多仅在此频率下运行验证 - 时间以毫秒为单位。 如果一个连接需要验证,但之前已经在此时间间隔内验证过,则不会再次验证。默认值为 30000(30 秒)。

【讨论】:

对于validationInterval,默认值应该是3000 (3 seconds),不是吗?

以上是关于如何让 Spring Boot 自动重新连接到 PostgreSQL?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot - 重新启动后重新连接到数据库

Maven Spring Boot 尝试连接到 MySQL

Spring Boot没有连接到RabbitMQ

无法将 spring-boot 2 服务连接到不同容器中的 mysql

如何从 Spring Boot 连接到在线 MongoDB 数据库?

如何将 AWS Elasticache Redis 集群连接到 Spring Boot 应用程序?