【问题标题】:spring boot + hibernate search + elastic search embedded fails to startspring boot + hibernate search + elastic search嵌入无法启动
【发布时间】:2016-10-22 03:38:25
【问题描述】:

我正在努力在 Spring Boot 设置中使用弹性搜索后端设置休眠搜索。

我拥有的是 spring boot 和以下依赖项。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    <version>1.4.0.M3</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
        <artifactId>hibernate-search-backend-elasticsearch</artifactId>
        <version>5.6.0.Alpha3</version>
</dependency>

发生的情况是,休眠搜索在弹性搜索完成启动之前初始化。

使用以下属性也可以公开其余接口

spring:
   data:
      elasticsearch:
         properties:
            http:
               enabled: true

引发异常

原因:org.apache.http.conn.HttpHostConnectException:连接到 localhost:9200 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] 失败:连接被拒绝: 连接

现在,我如何在这里定义依赖关系?

我尝试使用自定义 BeanFactoryPostProcessor 来注入对弹性搜索的依赖,但这似乎在自动配置场景中被忽略了。

有什么方法可以引入等到弹性搜索启动?

设置有效,当我将休眠index_management_strategy设置为NONE时,未配置索引并且忽略所有自定义分析器注释,默认为弹性搜索中的默认映射,无法在自动配置场景。

理想情况下,弹性搜索应该托管在 jvm 外部,但在测试场景中很方便。

【问题讨论】:

  • 它试图连接本地主机上的 ES 服务器,你显然没有运行它,所以它与休眠无关
  • 不完全是,通过spring boot自动配置的魔力启动了一个单节点实例,但是在后台

标签: elasticsearch spring-boot hibernate-search


【解决方案1】:

我了解到这是您在集成测试期间遇到的问题。

您可以看看我们如何在 Hibernate Search 本身的集成测试期间启动 ES,使用 Maven 插件确保服务器在测试之前启动: - https://github.com/hibernate/hibernate-search/blob/5.6.0.Beta1/elasticsearch/pom.xml#L341-L368

注意这使用自定义 ES 配置,即使它只是一个单节点集群,也可以快速启动: - https://raw.githubusercontent.com/hibernate/hibernate-search/5.6.0.Beta1/elasticsearch/elasticsearchconfiguration/elasticsearch.yml

Hibernate Search 使用 Jest 客户端连接到 ES,因此需要您启用 ES 的 HTTP 连接器:我们不要将此与 NodeClient 混淆,这是一种不同的操作模式。

如果您的问题与自动化测试无关,而是与生产集群有关,那么我建议您使用像 Kubernetes 这样的 Service Orchestrator。

【讨论】:

  • maven 插件是一个不错的选择,谢谢。但可能我需要的只是 JestHttpClient 的重试逻辑,在初始索引创建期间说 3 次,等待 10 秒 - 它只是立即失败,这会起作用。
  • 我宁愿确保首先启动 ES,但如果这是你之后的事情,那么你需要做的就是在 localhost/127.0.0.1 上发送一个带有任何自定义代码的 HTTP GET(和等待/重试)。无需修补 Jest。
  • 当然固定时间可能不是一个好主意,忙碌的等待正是我所追求的......目前唯一的问题是这一切都是由 spring boot 自动管理的 - 不想管理自己休眠..所以我需要在休眠开始自行初始化之前引入这个等待,但目前我缺少正确的注入点
【解决方案2】:

感谢 Spring Boot 团队的帮助,我得以解决问题 - 解决方案 here。

问题在于 EntityManagerFactory bean 和 Elasticsearch Client bean 之间没有依赖关系,因此无法保证 Elasticsearch 会在 Hibernate 之前启动。碰巧的是,Hibernate 首先启动,然后无法连接到 Elasticsearch。

这可以通过在两个 bean 之间建立依赖关系来解决。一个简单的方法是使用EntityManagerFactoryDependsOnPostProcessor 的子类:

@Configuration
static class ElasticsearchJpaDependencyConfiguration extends EntityManagerFactoryDependsOnPostProcessor {

    public ElasticsearchJpaDependencyConfiguration() {
        super("elasticsearchClient");
    }

}

现在只需将副本数设置为0,以修复单节点部署中集群的健康状态。这可以通过在application.properties 文件中指定一个附加属性来完成

spring.data.elasticsearch.properties.index.number_of_replicas= 0

【讨论】:

    【解决方案3】:

    我查看了 sprint-data 文档,看起来你误解了这篇文章(实际上这很令人困惑,大家不了解下面的技术吗?)

    默认情况下,实例将尝试连接到本地内存服务器(Elasticsearch 术语中的 NodeClient),但您可以通过设置 spring.data.elasticsearch.cluster-nodes 切换到远程服务器(即 TransportClient)到逗号分隔的“主机:端口”列表。

    NodeClient 不是“本地服务器”,它是一种特殊的ES 客户端。这个本地客户端可以连接到包含数据的 ES 集群节点,正如我在评论中所说,您没有运行任何 ES 数据节点。 阅读本文以更好地理解https://www.elastic.co/guide/en/elasticsearch/guide/current/_transport_client_versus_node_client.html

    【讨论】:

    • 感谢您对此进行调查。但是,当我在本地模式下为嵌入的 NodeClient 提供更多启动时间时,它会按预期工作。基本上ElasticsearchIndexManager 尝试在启动时使用http 创建索引。如果我将索引创建设置为 NONE,则会跳过此操作。所以稍后当需要索引元素时,NodeClient 启动并且一切正常(暴露 localhost:9200) - 除了没有创建索引映射。
    • 由于 NodeClient 是“有点”集群节点,你确实可以连接到 localhost:9200,但是如果你没有数据节点,它没有任何意义,它甚至不能用作模拟服务器。当然,您不能单独使用 NodeClient 创建任何索引或映射
    • 其实你可以用NodeBuilder API在同一个JVM中引导ES数据节点
    • 这正是 Spring Boot 自动配置给我的,docs.spring.io/spring-boot/docs/current/reference/html/…
    • 注: Hibernate Search 不使用“本地服务器”方法,而是使用 Jest 客户端通过 REST 协议进行连接。
    猜你喜欢
    • 2017-10-15
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 2022-08-24
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多