Springboot 2.0 - disable reconnecting to database
Asked Answered
P

2

3

After switching from spring-boot 1.5.x to spring-boot-2.x, when db connection is down, my spring application tries to reconnect to database constantly. I cannot even call a health check endpoint.

This only occurs in spring-boot-2.x

It might try to reconnect but, in my case, it should not block the whole application.

application.yml

spring:
  datasource:
    url: jdbc:postgresql://localhost/mydb?ssl=false
    username: dbuser
    password: dbpass
  jpa:
    hibernate:
      ddl-auto: create-drop

pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
            <version>LATEST</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
            <version>LATEST</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

I get the flood of the following error, when the db is down.

Error

2018-05-31 14:15:42.399 ERROR 90850 --- [onnection adder] org.postgresql.Driver                    : Connection error: 

org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:245) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.Driver.makeConnection(Driver.java:452) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.Driver.connect(Driver.java:254) ~[postgresql-42.2.2.jar:42.2.2]
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:117) [HikariCP-2.7.8.jar:na]
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:123) [HikariCP-2.7.8.jar:na]
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:365) [HikariCP-2.7.8.jar:na]
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:194) [HikariCP-2.7.8.jar:na]
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:460) [HikariCP-2.7.8.jar:na]
    at com.zaxxer.hikari.pool.HikariPool.access$100(HikariPool.java:71) [HikariCP-2.7.8.jar:na]
    at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:697) [HikariCP-2.7.8.jar:na]
    at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:683) [HikariCP-2.7.8.jar:na]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_161]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_161]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_161]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_161]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_161]
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_161]
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_161]
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_161]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_161]
    at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_161]
    at org.postgresql.core.PGStream.<init>(PGStream.java:69) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:156) ~[postgresql-42.2.2.jar:42.2.2]
    ... 16 common frames omitted
Pellet answered 31/5, 2018 at 12:21 Comment(5)
Have you waited long enough? In my case when the DB is down /actuator/health takes around 25 seconds because the health check itself tries to connect to the database.Elisabethelisabethville
As you can see in the stacktrace it's HikariPool's behavior, which became a default connection pool since Spring 2.0 release. Try research on that. Look for some properties.Festa
Does it make sense for your app to be up without a DB?Yetty
@MikhailKholodkov yes, I noticed it but I could not find a proper configuration or any explanation to disable the behavior or reduce the timeout value if there is at all.Pellet
@SimonMartinelli yes, after waiting for a certain time, it returns back to normal behavior. Now it's solved for me, I reduced the timeout value.Pellet
F
2

Following up on my comment, try these properties:

# Values in MS
spring
    datasource:
        hikari:
          connection-timeout: 60000
          validation-timeout: 60000
Festa answered 31/5, 2018 at 12:44 Comment(0)
Y
-1

Try adding these 2 properties in your configuration file:

spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
Yetty answered 31/5, 2018 at 12:33 Comment(1)
Given that Hikari is the standard connection pool in Spring Boot 2, your suggestion should have no effect or even makes things worse. First, Hikari always validates connections before handing them out. Second, a JDBC-4-compliant driver allows to validate the connection without having to set a validation query. Defining such a query anyway is discouraged.Sterile

© 2022 - 2024 — McMap. All rights reserved.