SmallRye Stork 遇到 Quarkus

上周,Quarkus Insights 聚焦了一个名为 SmallRye Stork 的新项目及其在 Quarkus 中的集成。在这篇博文中,我们将为您简要介绍 Stork。

此博文已更新,在配置 stork 属性时使用 quarkus. 前缀。自 Quarkus 2.8 起,需要此前缀。

面临什么问题?

如今,我们构建的系统由众多应用程序组成,通常称为微服务。系统的整体行为源于所有这些服务之间的交互。因此,一个微服务很可能会调用其他微服务。但这里有个棘手的问题。在 Kubernetes 或云等动态环境中,这些服务的位置可能会随时间而变化。那么,我们的微服务如何定位它需要调用的服务呢?

服务发现解决了这个问题,因为它提供了一种注册和查找服务的方法。但这会引发另一个问题。当同一服务有多个实例时会发生什么?微服务如何选择正确的实例?这种情况通常发生在同时有多个副本或版本可用时。因此,除了服务发现,我们还需要一种方法来选择正确的服务。

某些环境,例如 Kubernetes,提供了发现服务位置和负载均衡流量的方法。有些则不提供。在某些情况下,环境的能力不足以满足系统的需求。

SmallRye Stork

为了解决这些问题,我们创建了 SmallRye Stork。Stork 提供了以下两项功能:

  • 服务发现 - 让您能够定位需要调用的服务;

  • 服务选择 - 当存在多个实例时,让您能够选择正确的服务。

Stork 是什么?

SmallRye Stork 是一个服务发现和客户端负载均衡框架

它开箱即用地提供了与 Hashicorp Consul、Eureka 和 Kubernetes 的集成,并引入了几个负载均衡器(处理服务选择)实现,例如轮询。但 Stork 最显著的优势在于其可扩展性。您可以插入自己的服务发现机制,或者实现自己的、可能与业务相关的服务选择策略。

Stork 与 Quarkus

自 Quarkus 2.5.0.Final 起,Quarkus gRPC 和 Quarkus Reactive REST Client 可以使用 Stork 来处理服务的发现和选择。

您只需配置希望如何定位和选择服务即可。其余的将由客户端直接处理。

例如,要使用 Stork 来确定 REST Client Reactive 的实际地址,请将客户端 URI 的 scheme 设置为 stork,并将 URI 的 hostname 设置为 Stork 服务的名称。如果您的客户端 configKeymy-client,并且希望与 Hashicorp Consul 和 round-robin 负载均衡器一起使用,请在您的 `application.properties` 中添加以下内容:

application.properties
quarkus.rest-client.my-client.uri=stork://hello-service

# configure the discovery and selection of the hello-service
quarkus.stork.hello-service.service-discovery.type=consul
quarkus.stork.hello-service.service-discovery.consul-host=<consul host>
quarkus.stork.hello-service.service-discovery.consul-port=<consul port>

quarkus.stork.hello-service.load-balancer.type=round-robin

项目的文档逐步介绍了如何使用 Stork 与 REST Client,并以 Consul 和轮询负载均衡器为例。

服务选择可以非常高级。例如,最少响应时间策略会监控服务调用以选择最快的服务实例。

在 Quarkus 2.5 中,gRPC 扩展不传播调用统计信息,例如响应时间或遇到的错误。因此,依赖此数据的负载均衡器(如最少响应时间)将无法正常工作。我们正在努力解决这个问题,并希望能在 Quarkus 2.6 中实现。

演示及更多内容!

请观看 第 70 期 Quarkus Insights 以获取更详细的解释和示例。

演示使用了此项目作为客户端,每个步骤在 main 分支都有对应的提交。后端服务是此项目的实例,自定义服务发现服务器实现可以在此处找到。

结论

本文简要介绍了 SmallRye Stork 及其 Quarkus 集成。Stork 提供了一种定位和选择服务的方法。它简单且可定制。我们将很快更详细地介绍 Stork 的功能。

如果您有新功能想法,或遇到 bug,请通过创建 GitHub issue 告知我们。