如何使 Quarkus 服务器在其 DataSource 无法连接到数据库或即使数据库已关闭时启动

Posted

技术标签:

【中文标题】如何使 Quarkus 服务器在其 DataSource 无法连接到数据库或即使数据库已关闭时启动【英文标题】:How to make a Quarkus server starts when its DataSource is unable to connect to the DB or even if the database is down 【发布时间】:2021-06-02 09:36:00 【问题描述】:

我想启动我的 quarkus 应用程序,如果数据库关闭,它不会影响我的启动。

我的代码:https://github.com/Uenderley/quarkus-datasources

我的 pom.xml

  <properties>
    <compiler-plugin.version>3.8.1</compiler-plugin.version>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus-plugin.version>1.11.3.Final</quarkus-plugin.version>
    <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
    <quarkus.platform.version>1.11.3.Final</quarkus.platform.version>
    <surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
  </properties>

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-hibernate-orm</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-hibernate-orm-panache</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jdbc-postgresql</artifactId>
    </dependency>

application.properties

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=postgres
quarkus.datasource.password=postgres
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5433/users_db
quarkus.datasource.health.enabled=false
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.datasource.jdbc.min-size=0

当我在 postgres 关闭时尝试启动我的应用程序时出错

WARN  [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (Quarkus Main Thread) HHH000342: Could not obtain connection to query metadata: org.postgresql.util.PSQLException: Connection to localhost:5433 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:303)
        at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:51)
        at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:225)
        at org.postgresql.Driver.makeConnection(Driver.java:465)
        at org.postgresql.Driver.connect(Driver.java:264)
        at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:200)
        at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:452)
        at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:434)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:65)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1126)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.net.ConnectException: Conexão recusada (Connection refused)
        at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
        at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
        at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.base/java.net.Socket.connect(Socket.java:609)
        at org.postgresql.core.PGStream.createSocket(PGStream.java:231)
        at org.postgresql.core.PGStream.<init>(PGStream.java:95)
        at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:98)
        at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213)
        ... 12 more

2021-03-03 14:21:56,494 WARN  [io.agr.pool] (agroal-11) Datasource '<default>': Connection to localhost:5433 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
2021-03-03 14:21:56,495 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (Quarkus Main Thread) SQL Error: 0, SQLState: 08001
2021-03-03 14:21:56,495 ERROR [org.hib.eng.jdb.spi.SqlExceptionHelper] (Quarkus Main Thread) Connection to localhost:5433 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
2021-03-03 14:21:56,526 ERROR [io.qua.run.Application] (Quarkus Main Thread) Failed to start application (with profile dev): java.net.ConnectException: Conexão recusada (Connection refused)
        at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
        at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
        at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.base/java.net.Socket.connect(Socket.java:609)
        at org.postgresql.core.PGStream.createSocket(PGStream.java:231)
        at org.postgresql.core.PGStream.<init>(PGStream.java:95)
        at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:98)
        at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213)
        at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:51)
        at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:225)
        at org.postgresql.Driver.makeConnection(Driver.java:465)
        at org.postgresql.Driver.connect(Driver.java:264)
        at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:200)
        at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:452)
        at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:434)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:65)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1126)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)

Quarkus application exited with code 1
Press Enter to restart or Ctrl + C to quit
2021-03-03 14:21:56,528 INFO  [io.qua.dep.dev.IsolatedDevModeMain] (main) Attempting to start hot replacement endpoint to recover from previous Quarkus startup failure

我知道spring boot的这些属性:

spring.datasource.continue-on-error=true

spring.datasource.initialization-mode=never

【问题讨论】:

不清楚你想实现什么。如果数据库不可用,您是否希望您的应用程序在启动时失败?您希望您的应用程序在上次连接失败后重新建立连接吗? 看起来他希望服务启动,即使DB连接不成功。 【参考方案1】:

如果数据库仅在您调用服务时关闭,则可能尝试通过方法注入 AgroalDataSource 以失败。

删除 @Inject 并将其添加到您的服务方法中:

AgroalDataSource datasource = CDI.current().select(AgroalDataSource.class).get();

导入类:

import javax.enterprise.inject.spi.CDI;

【讨论】:

以上是关于如何使 Quarkus 服务器在其 DataSource 无法连接到数据库或即使数据库已关闭时启动的主要内容,如果未能解决你的问题,请参考以下文章

Quarkus技术系列「云原生架构实战」配置参考指南相关的功能机制配置介绍分析

Quarkus:如何在微服务之间进行身份验证?

Quarkus:集成测试 - 如何模拟 OIDC?

如何诊断 Quarkus REST 服务 OIDC 错误(特别是 403 禁止)?

」打造基于Quarkus的云原生微服务框架实践的理论知识基础

Quarkus技术系列「云原生架构基建」打造基于Quarkus的云原生微服务框架实践