[spring-projects/spring-boot]支持 Elasticsearch RestClientBuilder 自动配置,无需 RestHighLevelClient

2024-05-14 352 views
3

在此提交之前,Spring Boot 只会自动配置RestHighLevelClientRestClientBuilder如果RestHighLevelClient 存在。这是在 1d73d4eda75ef0d18c747c57aa2b3385674483c7 中完成的,作为https://github.com/spring-projects/spring-boot/issues/22358的一部分

RestClient当暴露RestHighLevelClientRestHighLevelClient不存在时,此提交会在 Spring Boot 中恢复对 bean 的暴露。它允许以与 和 的RestClientBuilder类似方式使用 Spring Boot 自动配置及其定制器。现在 的存在是可选的。这为可能添加对基于相同版本的新Elasticsearch Java 客户端的支持打开了大门。 RestTeamplateBuilderWebClient.Builderorg.elasticsearch.client:elasticsearch-rest-high-level-clientRestClient


将 暴露为RestClientbean 并不是此 PR 中最重要的事情。我宁愿说,RestClientBuilder暴露为 bean 的事实是最重要的部分。这允许用户依赖 Spring Boot 提供的配置机制,RestClientBuilder而不是依赖现已弃用的 Elasticsearch Rest High Level Client。

回答

8

我没有对 Gradle Wrapper 进行任何更改。 Gradle Wrapper 操作本身似乎存在一些问题

4

我创建此 PR 的最大原因是将其RestClientBuilder作为 bean 来获取,以便依赖 Spring 属性/定制器。根据当前的设置,您必须拥有elasticsearch-rest-high-level-client才能创建自己的RestClient.

原因是

https://github.com/spring-projects/spring-boot/blob/83e44305122a9bd45194cd5db649ad3a12b64690/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration。 java#L41-L42

我们有一个大量使用 Spring Boot 的平台,我们直接使用RestClient而不是RestHighLevelClient.我们开始完全删除依赖项,因为由于许可问题,我们希望完全不依赖它。自 7.11 起,高级客户端不再获得 Apache 2.0 许可。我以为一切都会按预期进行,但后来就RestClientBuilder不再存在了。

添加RestClient作为 bean 是对我们最初要求的补充。老实说,我认为将它公开为 bean 并不那么复杂,因为它可以通过RestHighLevelClient#getLowLevelClient轻松地公开,如果RestHighLevelClient不存在,则可以轻松地通过RestClientBuilder.这就是我这样做的原因。

即使您只部分集成它(没有新的bean),我们也可以轻松做到


@Bean
public RestClient elasticsearchRestClient(RestTemplateBuilder builder) {
    return builder.build();
}

并且在我们自己的应用程序中拥有该RestClientbean,而不需要依赖于Spring Boot RestHighLevelClient,也不需要复制已经在Spring Boot中完成的事情。


除了所有这些之外,还有OpenSearch有它自己的东西。无需讨论太多细节,出于我们自己的简单目的,可以使用一个集群RestClient与两种类型的集群进行通信。


简而言之,对于我们必须在 OpenSearch 和 Elasticsearch 上维护对我们自己的东西的支持来说,仅使用低级客户端是很有意义的。我希望您能考虑到这一点并修改您的决定。非常感谢您的理解

6

感谢@filiphr 提供的背景信息,这非常有用。

对此,我认为我们应该:

  • 带回RestClient或其构建者作为豆子。这应该允许 OpenSearch 用例
  • 安排对新官方客户端的支持并弃用当前客户端
3

还有一些事情,我忘了添加到这个 PR 中。也需要ElasticSearchRestHealthContributorAutoConfiguration适应。

理想情况下,健康贡献者将适合仅使用RestClient或以某种方式组合使用(如果RestHighLevelClient存在的话)。例如,所有RestClient豆类以及RestHighLevelClient#getRestLowLevelClient()未作为豆类暴露的豆类。需要ElasticsearchRestHealthIndicator调整为仅将 用作RestClient构造函数,以便不强制依赖于RestHighLevelClient。如果这样做,那么旧的RestHighLevelClient和新的 Elasticsearch Java 客户端都可以使用同一个类。

如果您认为同意我的建议,我当然可以提供 PR 和/或调整此 PR。

6

我希望最终的一个论点是,删除对RestHighLevelClient刚刚从我们的最终 jar 中删除的约 20MB 的依赖。不确定这样的事情从你的角度来看是否重要,但我也想分享这一点

1

非常感谢@filiphr 的所有见解。

我们刚刚作为一个团队讨论过这个问题,并决定:

  1. RestClient作为豆子带回来;我们最初认为它对于实际应用价值较低,但随着Elasticsearch生态系统的最新变化,最好拥有它。
  2. 调整健康贡献者仅依赖于低水平RestClient
  3. 在 2.7 中弃用RestHighLevelClient,请参阅#28598
  4. 支持 2.7 中的新内容ElasticsearchClient作为替代,请参阅#28597

您能否调整此 PR 以解决 1) 和 2) 问题?请注意,我们已计划在 2.7 版本中进行此操作,因此不必着急,因为我们将首先专注于发布 2.6 版本并修复关键错误。

0

非常感谢@bclozel 的这个决定。

我将调整此 PR 以考虑 1) 和 2)。

当 the不存在但存在时,将其暴露RestClientBuilder为 bean怎么样?您是否会接受 2.6 的单独 PR 来实现此目的?RestHighLevelClientRestClientBuilder

我已经成功地用 2.5 实现了我所需要的,但是我这样做的方式并不是最好的方法,因为我正在用 做一些令人讨厌的魔法ImportSelector,而且我宁愿摆脱我们拥有的那些令人讨厌的魔法。

4

当 RestHighLevelClient 不存在但 RestClientBuilder 存在时,将 RestClientBuilder 公开为 bean 怎么样?您是否会接受 2.6 的单独 PR 来实现此目的?

公开RestClientBuilder可能适合您的情况,但我想知道这是否是正确的选择:我不认为我们通常希望RestClient在同一个应用程序中拥有多个实例?这会创建多个 HTTP 客户端实例,对吧?即使应用程序本身只创建一个,我们也需要将其重用于健康指示器吗?

不幸的是,2.6 周期有点晚了,所以如果我们想在这里引入更改,它必须非常安全。

8

@bclozel 我认为我已经按照您的要求改编了 PR。请看一下,如果还有什么需要做的,请告诉我。

还改编了使用ElasticsearchRestHealthIndicator。我不推荐使用构造函数RestHighLevelClient。不确定你们的移除政策是什么。理想情况下,我想摆脱构造函数,因为当前状态下的不存在ElasticsearchRestHealthIndicator时不可用。RestHighLevelClient我认为该类根本不会加载。


公开RestClientBuilder可能适合您的情况,但我想知道这是否是正确的选择:我不认为我们通常希望RestClient在同一个应用程序中拥有多个实例?这会创建多个 HTTP 客户端实例,对吧?即使应用程序本身只创建一个,我们也需要将其重用于健康指示器吗?

暴露RestClientBuilder并不意味着将会有多个 实例RestClient。需要调用 build 方法才能RestClient创建 a。这意味着从 Spring Boot 2.6 的角度来看,当RestHighLevelClient不存在时,将会有一个类型为 的 bean RestClientBuilder。然后用户可以选择并决定如何处理它RestClientBuilder。为了减少变化量健康指标不会使用它。人们将需要在 2.6 中公开自己的健康指标。正如我在上一段中提到的,ElasticsearchRestHealthIndicator如果没有 .current 就无法使用RestHighLevelClient

5

@filiphr你是对的,我忘记了我们已经将构建器暴露为一个bean。我需要更深入地观察。

9

@bclozel 我会尝试做一个小提案作为单独的 PR。然后你可以决定你想做什么

0

@bclozel 我在 PR #28655 中提出了一个提案。请看一下并告诉我您的想法。这个公关和那个当然有一些重叠。但是,根据您的决定,如果需要,我可以在其他 PR 之上调整此 PR。

5

备案2.7.x已升级至Elasticsearch 7.16.2

7

备案2.7.x已升级至Elasticsearch 7.16.2

妈的,我先是在main上rebase,后来发现main和2.7.x不一样,所以就在2.7.x上做了。我将尝试考虑 2.7.x 中的新更改并修复冲突。

基本上,我需要确保没有弃用警告,对吗?

6

@wilkinsona 我同意你的观点,代码随着你的更改而简化。但是,您的更改意味着只有在类路径上有 时,您才能进行 Elasticsearch 运行状况检查RestHighLevelClient,因为 的加载ElasticsearchRestHealthIndicator将由于RestHighLevelClient在其构造函数之一中使用而失败。

RestHighLevelClient我个人认为,如果类路径上没有 Elasticsearch 自动配置,则无需丢失。由于ElasticSearchRestHealthContributorAutoConfiguration它的变化也意味着当您只有可用时应用程序将无法正常启动RestClient

如果这是 Boot 团队想要做的事情,那么我完全同意。但是,我要求您重新考虑并在没有 RestHighLevelClient 的情况下进行健康检查。

9

这是无意的过度简化。感谢您抓住它,@filiphr。我再看一下。需要一个RestClientbean 来自动配置运行状况指示器看起来可能是一个很好的中间立场。

1

需要一个RestClientbean 来自动配置运行状况指示器看起来可能是一个很好的中间立场。

这与自动配置无关。自动配置工作正常,并且如果RestClient存在 bean,它会自动配置。问题是,当类不存在ElasticsearchRestHealthIndicator时,加载将会失败。RestHighLevelClient

感谢您再看一遍。

8

非常感谢您带回旧的更改@wilkinsona。真的很感激。

1

@wilkinsona 我们 opensearch 用户是否希望在 2.7.0 之后继续使用 opensearch.RestHighLevelClient ?

5

Spring Boot 没有针对 OpenSearch 的任何自动配置,因此我们对您应该做什么没有任何期望。

1

@nightswimmings 据我所知,您可以继续将 ElasticsearchRestClient与 OpenSearch 结合使用。但你不能使用它RestHighLevelClient

3

谢谢 filiphr,我们已经有了所有分叉的 opensearch 客户端代码,只是我不知道如果您使用的是 opensearch 风格的 els,我不知道是否会对新的自动配置和弃用产生任何影响,但如果 Boot 不考虑后者,那么这不是问题