You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Quarkus原生容器连接ElasticSearch的连接拒绝问题

问题

我把集成了hibernate-orm-panache、resteasy-reactive、PostgreSQL的Quarkus应用打包成Docker容器后,能正常连接本地PostgreSQL,但开发模式下正常的ElasticSearch集成,在原生镜像容器中启动时出现「Elasticsearch request failed:Connection refused」错误。配置里quarkus.elasticsearch.hosts设为localhost:9200,先启动ElasticSearch集群再启动Quarkus也没用。

配置文件

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=postgres
quarkus.datasource.password=postgrespw
quarkus.datasource.jdbc.url=jdbc:postgresql://192.168.5.45:5432/b2data

#quarkus.hibernate-orm.log.sql=true

quarkus.hibernate-search-orm.elasticsearch.version=7
quarkus.hibernate-search-orm.automatic-indexing.synchronization.strategy=sync

quarkus.elasticsearch.hosts = localhost:9200
#quarkus.elasticsearch.port = 9200
#quarkus.elasticsearch.devservices.enabled = false

依赖

<dependencies>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive-jackson</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-orm-panache</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-search-orm-elasticsearch</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jdbc-postgresql</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-arc</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-junit5</artifactId>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

错误日志

2022-11-03 15:10:05,879 ERROR [org.hib.sea.eng.rep.spi.RootFailureCollector] (JPA Startup Thread: <default>) HSEARCH000521: Hibernate Search encountered a failure during bootstrap; continuing for now to list all problems, but the process will ultimately be aborted.
Context: default backend
Failure:: org.hibernate.search.util.common.SearchException: HSEARCH400080: Unable to detect the Elasticsearch version running on the cluster: HSEARCH400007: Elasticsearch request failed: Connection refused
Request: GET  with parameters {}
Response: (no response)
        at org.hibernate.search.backend.elasticsearch.client.impl.ElasticsearchClientUtils.getElasticsearchVersion(ElasticsearchClientUtils.java:59)
        at org.hibernate.search.backend.elasticsearch.impl.ElasticsearchLinkImpl.initVersion(ElasticsearchLinkImpl.java:200)
        at org.hibernate.search.backend.elasticsearch.impl.ElasticsearchLinkImpl.onStart(ElasticsearchLinkImpl.java:142)
        at org.hibernate.search.backend.elasticsearch.impl.ElasticsearchBackendImpl.start(ElasticsearchBackendImpl.java:148)
        at org.hibernate.search.engine.common.impl.BackendNonStartedState.start(BackendNonStartedState.java:48)
        at org.hibernate.search.engine.common.impl.SearchIntegrationPartialBuildStateImpl$SearchIntegrationFinalizerImpl.finalizeIntegration(SearchIntegrationPartialBuildStateImpl.java:174)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationPartialBuildState.doBootSecondPhase(HibernateOrmIntegrationPartialBuildState.java:75)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.bootNow(HibernateOrmIntegrationBooterImpl.java:176)
        at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
        at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
        at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateSearchSessionFactoryObserver.sessionFactoryCreated(HibernateSearchSessionFactoryObserver.java:41)
        at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:402)
        at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:74)
        at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:72)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:165)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:66)
        at java.lang.Thread.run(Thread.java:833)
        at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:705)
        at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:202)
Caused by: org.hibernate.search.util.common.SearchException: HSEARCH400007: Elasticsearch request failed: Connection refused
Request: GET  with parameters {}
Response: (no response)
        at org.hibernate.search.backend.elasticsearch.client.impl.ElasticsearchClientUtils.tryGetElasticsearchVersion(ElasticsearchClientUtils.java:83)
        at org.hibernate.search.backend.elasticsearch.client.impl.ElasticsearchClientUtils.getElasticsearchVersion(ElasticsearchClientUtils.java:56)
        ... 22 more
Caused by: org.hibernate.search.util.common.SearchException: Connection refused
        at org.hibernate.search.util.common.impl.Throwables.toRuntimeException(Throwables.java:33)
        at org.hibernate.search.util.common.impl.Futures.unwrappedExceptionJoin(Futures.java:196)
        at org.hibernate.search.backend.elasticsearch.client.impl.ElasticsearchClientUtils.tryGetElasticsearchVersion(ElasticsearchClientUtils.java:67)
        ... 23 more
Caused by: java.net.ConnectException: Connection refused
        at com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_VA_LIST_ConnectException_constructor_026ed3e065cc052585fca43de83265b2d1381f28(JNIJavaCallWrappers.java:0)
        at sun.nio.ch.Net.pollConnect(Net.java)
        at sun.nio.ch.Net.pollConnectNow(Net.java:672)
        at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946)
        at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvent(DefaultConnectingIOReactor.java:174)
        at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvents(DefaultConnectingIOReactor.java:148)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:351)
        at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)
        at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
        ... 3 more

2022-11-03 15:10:05,882 ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): org.hibernate.search.util.common.SearchException: HSEARCH000520: Hibernate Search encountered failures during bootstrap. Failures:

    default backend:
        failures:
          - HSEARCH400080: Unable to detect the Elasticsearch version running on the cluster: HSEARCH400007: Elasticsearch request failed: Connection refused
            Request: GET  with parameters {}
            Response: (no response)
        at org.hibernate.search.engine.reporting.spi.RootFailureCollector.checkNoFailure(RootFailureCollector.java:53)
        at org.hibernate.search.engine.common.impl.SearchIntegrationPartialBuildStateImpl$SearchIntegrationFinalizerImpl.finalizeIntegration(SearchIntegrationPartialBuildStateImpl.java:177)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationPartialBuildState.doBootSecondPhase(HibernateOrmIntegrationPartialBuildState.java:75)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.bootNow(HibernateOrmIntegrationBooterImpl.java:176)
        at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
        at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
        at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateSearchSessionFactoryObserver.sessionFactoryCreated(HibernateSearchSessionFactoryObserver.java:41)
        at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:402)
        at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:74)
        at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:72)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:165)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:66)
        at java.lang.Thread.run(Thread.java:833)
        at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:705)
        at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:202)

解决方案

核心问题是Docker容器内的localhost指向容器自身网络,而非宿主机,所以你的Quarkus容器在尝试连接localhost:9200时,其实是在容器内部找ElasticSearch,自然会连接失败。以下是几种可行的解决方法:

方法1:替换localhost为宿主机IP

直接把配置中的quarkus.elasticsearch.hosts改成宿主机的IP地址(和你连接PostgreSQL用的192.168.5.45一致):

quarkus.elasticsearch.hosts = 192.168.5.45:9200

注意:要确保ElasticSearch的配置中network.host不是仅绑定localhost,需要允许外部访问(比如设为0.0.0.0),否则宿主机IP也无法访问。

方法2:用Docker Compose统一管理容器网络

如果用Docker Compose部署ElasticSearch和Quarkus,两者会自动加入同一个默认网络,此时可以用服务名作为主机名访问:

  1. 编写docker-compose.yml:
version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    ports:
      - "9200:9200"
  quarkus-app:
    build: .
    environment:
      - QUARKUS_ELASTICSEARCH_HOSTS=elasticsearch:9200
      - QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://192.168.5.45:5432/b2data
    ports:
      - "8080:8080"
    depends_on:
      - elasticsearch
  1. 修改Quarkus配置,或者通过环境变量覆盖(如上),此时elasticsearch就是ElasticSearch容器的主机名,无需IP地址。

方法3:使用Docker主机网络模式(快速测试用,不推荐生产)

启动Quarkus容器时加上--network host参数,让容器直接使用宿主机的网络栈,此时容器内的localhost就等同于宿主机的localhost:

docker run --network host your-quarkus-image

这种方法会破坏容器的网络隔离性,生产环境不建议使用,但可以快速验证问题是否来自网络隔离。


内容的提问来源于stack exchange,提问作者ko.alen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:10:50