返回介绍

4.2 云中的服务发现

发布于 2025-04-22 21:54:06 字数 3772 浏览 0 评论 0 收藏

基于云的微服务环境的解决方案是使用服务发现机制,这一机制具有以下特点。

  • 高可用 ——服务发现需要能够支持“热”集群环境,在服务发现集群中可以跨多个节点共享服务查找。如果一个节点变得不可用,集群中的其他节点应该能够接管工作。
  • 点对点 ——服务发现集群中的每个节点共享服务实例的状态。
  • 负载均衡 ——服务发现需要在所有服务实例之间动态地对请求进行负载均衡,以确保服务调用分布在由它管理的所有服务实例上。在许多方面,服务发现取代了许多早期 Web 应用程序实现中使用的更静态的、手动管理的负载均衡器。
  • 有弹性 ——服务发现的客户端应该在本地“缓存”服务信息。本地缓存允许服务发现功能逐步降级,这样,如果服务发现服务变得不可用,应用程序仍然可以基于本地缓存中维护的信息来运行和定位服务。
  • 容错 ——服务发现需要检测出服务实例什么时候是不健康的,并从可以接收客户端请求的可用服务列表中移除该实例。服务发现应该在没有人为干预的情况下,对这些故障进行检测,并采取行动。

在接下来的几节中,我们将:

  • 了解基于云的服务发现代理的工作方式的概念架构;
  • 展示即使在服务发现代理不可用时,客户端缓存和负载均衡如何使服务能够继续发挥作用;
  • 了解如何使用 Spring Cloud 和 Netflix 的 Eureka 服务发现代理实现服务发现功能。

4.2.1 服务发现架构

为了开始讨论服务发现架构,我们需要了解 4 个概念。这些一般概念在所有服务发现实现中是共通的。

  • 服务注册 ——服务如何使用服务发现代理进行注册?
  • 服务地址的客户端查找 ——服务客户端查找服务信息的方法是什么?
  • 信息共享 ——如何跨节点共享服务信息?
  • 健康监测 ——服务如何将它的健康信息传回给服务发现代理?

图 4-2 展示了这 4 个概念的流程,以及在服务发现模式实现中通常发生的情况。

图 4-2 随着服务实例的添加与删除,它们将更新服务发现代理,并可用于处理用户请求

在图 4-2 中,启动了一个或多个服务发现节点。这些服务发现实例通常是独立的,在它们之前一般不会有负载均衡器。

当服务实例启动时,它们将通过一个或多个服务发现实例来注册它们可以访问的物理位置、路径和端口。虽然每个服务实例都具有唯一的 IP 地址和端口,但是每个服务实例都将以相同的服务 ID 进行注册。服务 ID 是唯一标识一组相同服务实例的键。

服务通常只在一个服务发现实例中进行注册。大多数服务发现的实现使用数据传播的点对点模型,每个服务实例的数据都被传递到服务发现集群中的所有其他节点。

根据服务发现实现机制的不同,传播机制可能会使用硬编码的服务列表来进行传播,也可能会使用像“gossip”或“infection-style”协议这样的多点广播协议,以允许其他节点在集群中“发现”变更。

最后,每个服务实例将通过服务发现服务去推送服务实例的状态,或者服务发现服务从服务实例拉取状态。任何未能返回良好的健康检查信息的服务都将从可用服务实例池中删除。

服务在向服务发现服务进行注册之后,这个服务就可以被需要使用这项服务功能的应用程序或其他服务使用。客户端可以使用不同的模型来“发现”服务。在每次调用服务时,客户端可以只依赖于服务发现引擎来解析服务位置。使用这种方法,每次调用注册的微服务实例时,服务发现引擎就会被调用。但是,这种方法很脆弱,因为服务客户端完全依赖于服务发现引擎来查找和调用服务。

一种更健壮的方法是使用所谓的客户端负载均衡。图 4-3 阐示了这种方法。

图 4-3 客户端负载均衡缓存服务的位置,以便服务客户端不必在每次调用时联系服务发现

在这个模型中,当服务消费者需要调用一个服务时:

(1)它将联系服务发现服务,获取它请求的所有服务实例,然后在服务消费者的机器上本地缓存数据。

(2)每当客户端需要调用该服务时,服务消费者将从缓存中查找该服务的位置信息。通常,客户端缓存将使用简单的负载均衡算法,如“轮询”负载均衡算法,以确保服务调用分布在多个服务实例之间。

(3)然后,客户端将定期与服务发现服务进行联系,并刷新服务实例的缓存。客户端缓存最终是一致的,但是始终存在这样的风险:在客户端联系服务发现实例以进行刷新和调用时,调用可能会被定向到不健康的服务实例上。

如果在调用服务的过程中,服务调用失败,那么本地的服务发现缓存失效,服务发现客户端将尝试从服务发现代理刷新数据。

现在,让我们使用通用服务发现模式,并将它应用到 EagleEye 问题域。

4.2.2 使用 Spring 和 Netflix Eureka 进行服务发现实战

现在,我们将通过创建一个服务发现代理来实现服务发现,然后通过代理注册两个服务。接着,通过使用服务发现检索到的信息,让一个服务调用另一个服务。Spring Cloud 提供了多种从服务发现代理查找信息的方法。本书将介绍每种方法的优点和缺点。

Spring Cloud 项目再一次让这种创建变得极其简单。本书将使用 Spring Cloud 和 Netflix 的 Eureka 服务发现引擎来实现服务发现模式。对于客户端负载均衡,本书使用 Spring Cloud 和 Netflix 的 Ribbon 库。

在前两章中,我们尽可能让许可证服务保持简单,并将组织名称和许可证数据包含在许可证中。在本章中,我们将把组织信息分解到它自己的服务中。

当许可证服务被调用时,它将调用组织服务以检索与指定的组织 ID 相关联的组织信息。组织服务的位置的实际解析存储在服务发现注册表中。本例将使用服务发现注册表注册两个组织服务实例,然后使用客户端负载均衡来查找服务,并在每个服务实例中缓存注册表。图 4-4 展示了这个过程。

图 4-4 通过许可证服务和组织服务实现客户端缓存和 Eureka,可以减轻 Eureka 服务器上的负载,
并提高 Eureka 不可用时的客户端稳定性

(1)随着服务的启动,许可证和组织服务将通过 Eureka 服务进行注册。这个注册过程将告诉 Eureka 每个服务实例的物理位置和端口号,以及正在启动的服务的服务 ID。

(2)当许可证服务调用组织服务时,许可证服务将使用 Netflix Ribbon 库来提供客户端负载均衡。Ribbon 将联系 Eureka 服务去检索服务位置信息,然后在本地进行缓存。

(3)Netflix Ribbon 库将定期对 Eureka 服务进行 ping 操作,并刷新服务位置的本地缓存。

任何新的组织服务实例现在都将在本地对许可证服务可见,而任何不健康实例都将从本地缓存中移除。

接下来,我们将通过建立 Spring Cloud Eureka 服务来实现这个设计。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。