深入了解服务发现

为什么需要服务发现?

当我们需要通过 REST API 或者其他RPC去请求其他服务的时候。首先需要做的一件事是在网络中通过 IP 和 端口 找到请求目标的服务实例。传统的应用往往是绑定在固定的 IP 和端口之上,这样我们就能在访问前的知道目标的网络地址了。在现代云原生的微服务应用上,这种方式不再那么可靠。云原生的服务实例往往是在创建后进行动态绑定的。并且,随着应用集群的扩容、缩容、滚动升级等操作,服务实例也是一直在动态变化着。在这种动态的场景之下,就需要用到“服务发现”来帮我们定位到目标应用。

我们先从大家比较熟悉的模式入手。通过场景的方式来了解服务发现,看看这个里面藏着什么我们平时忽略掉的内容。

客户端发现(client-side discovery)模式

当我们使用客户端发现模式时,客户端(Instance)主动注册到服务注册中心(Service Registry)。当其他客户端(Source Instance)需要访问的时候,先从注册中心(Service Registry)查询对应的服务实例组,并通过负载均衡(Load Balance)算法计算出具体需要访问的网络位置。为了保证服务实例的持续可用性,客户端会通过心跳机制(Heartbeat)持续注册,当超过心跳时间还未注册的服务实例会被服务注册中心移除出服务实例组。

其实,我们熟知的 Netflix 微服务套件便是使用客户端发现模式实现的。Netflix Eureka 承担了上图中 Service Registry 的功能,它通过 REST API 提供了服务的注册与查询可用服务实例组。

Netflix Ribbon 通过 Eureka 查询可用服务实例组,并按照设定的负载均衡算法,请求服务实例组中其中一个。
客户端模式的服务发现的优点与缺点并重。这种模式相对简单,除了服务注册之外,没有其他活动部件。此外,由于客户端知道可用的服务实例,因此它可以做出适应自身需求的负载均衡选择,例如一致地使用轮询或 Hash 等方式。这种模式有着个显著的缺点,它将客户端与服务注册中心耦合在一起。你必须为服务客户端使用的每种编程语言和框架实现客户端服务发现逻辑。

我们来换种思路,看看通过服务器端统一控制服务发现又会是什么样的情形。

服务器端发现(server-side discovery)模式

服务器端发现模式,通过一个独立的负载均衡器(LoadBalancer)去访问其他的服务实例。查询可用实例组的任务交给了负载均衡器,同时,负载均衡器负责路由每个请求到对应的服务实例上。这种模式与客户端发现模式不同点是,将客户端中的服务实例查询与负载均衡剥离出来,用一个单独的负载均衡器来承担这项任务。

AWS Elastic Load Balancer(ELB)就是服务器端发现模式的实现之一。 ELB 通常用于负载均衡来自Internet 的外部流量。 但是,也可以使用 ELB 对 Virtual Private Cloud (VPC) 内部的流量进行负载平衡。客户端使用 ELB 发出请求。 ELB 负载均衡流量到一组注册的Elastic Compute Cloud (EC2) 实例或 EC2 Container Service (ECS) 容器。不过,有一点比较特殊的是,这里没有单独的服务注册中心,EC2 和 ESC 们把自己直接注册到 ELB 上了。

服务器端发现模式也有着它的优点和缺点。这种模式的一大好处是发现的细节是从客户端抽象出来的,客户端只需向负载均衡器发出请求。这消除了为服务客户端使用的每种编程语言和框架实现发现逻辑的需要。然而,这种模式也有一些缺点,除非部署环境提供负载均衡器,否则它是另一个需要设置和管理的高可用性系统组件。

其他扩展

服务发现的两大模式已经讲完了,风靡全球的 Kubernates 是使用的服务器端模式还是客户端模式呢,让我们一起来分析分析。

Kubernates 用一个对象完成了这个过程——Service(这个命名…)。Kubernetes 一般会在一组完成同样工作的 Pod 之前放置一个 Service 对象,每个 Service 对象会由 Kubernates 分配一个固定的DNS地址,便于其他需要使用这组 Pods 的服务用来访问。例如在你的商品服务 Pods 前放一个 Service(goods-service),在订单服务 Pods 之前放了 DNS 是 Order-Service 的 Service。当请求来了后,Service 负责把流量负载均衡到 Pod。Service 管辖下的 Pods 会因为伸缩、更新、故障等情况发生变化,而 Service 会对这些变化进行跟踪。所以看起来Kubernates ,使用的是服务器端模式来实现的服务发现。同时,我们又发现了另外一个特点,大多数实际中的服务器端模式的使用场景中,LoadBalancer 与 Service Registry这两个组件都被整合到了同一个组件中。

下面的服务注册是服务发现的关键部分。让我们看看它又有什么玄机。

服务注册中心

服务注册中心是一个包含服务实例网络位置的数据库,它需要高度的可用性与实时性。 虽然,客户端可以缓存从服务注册中心获得的网络位置。 但是,该信息最终会过时。一旦信息过时,客户端将无法找到需要通信的服务实例。因此,服务注册中心由一组使用复制协议的服务器来保持一致性的。

前面提到过的 Netflix Eureka 就是一个经典的服务注册中心实现。Eureka 通过 REST API 的方式来提供对外的服务实例查询与注册的能力。如果,一个服务只需调用 Eureka 提供的 POST API,便可以把自己的网络位置注册到它上面。接下来,服务还需要每隔 30s 调研 PUT API来持续刷新自己的状态。当一些服务超过 30s 还没有将自己刷新,那 Eureka 会将服务的状态改为不可用。当然,服务还可以通过 DELETE 接口将自己从 Eureka 的服务列表中删除。当你需要调用其他服务的时候,只需要调用 Eureka 提供的 GET API 便可以查询的对应的服务的最新列表了。

此外,如前所述,某些系统(例如 Kubernetes、AWS)没有明确的服务注册中心。 相反,服务注册中心只是基础设施的一个内置部分。现在我们已经了解了服务注册中心的概念,让我们看看服务实例是如何注册到服务注册中心的。

服务注册的选择

如前所述,服务实例必须在服务注册中心注册和注销。 有几种不同的方式来处理注册和注销。 一种选择是让服务实例自行注册,即自注册模式。 另一种选择是让其他系统组件管理服务实例的注册,即第三方注册模式。 我们先来看看自注册模式。

自注册模式

使用自注册模式时,服务实例负责向服务注册中心注册和注销自己。 此外,服务实例会发送心跳请求来持续保持注册状态。

这种方法的一个很好的例子是 Netflix Eureka。Eureka 客户端处理服务实例注册和注销的所有方面情况。 Spring Cloud 项目实现了包括服务发现在内的各种模式,可以轻松地向 Eureka 自动注册服务实例。您只需在Main 方法的类上使用 @EnableEurekaClient 来注明。

自注册模式的主要好处是它相对简单,不需要任何其他系统组件。 然而,一个主要的缺点是它将服务实例耦合到服务注册中心。 您必须在您的服务使用的每种编程语言和框架中实现注册代码。另一种将服务与服务注册分离的方法是第三方注册模式。

三方注册模式

使用第三方注册模式时,服务实例不负责向服务注册中心注册自己。相反,通过服务注册器(Registrar)这个系统组件来处理注册。服务注册器通过轮询部署环境或订阅事件来跟踪对运行实例集的更改。 当它注意到一个新的可用服务实例时,它会向服务注册中心注册该实例。 服务注册器还会注销已终止的服务实例。

服务注册器的一个例子是开源 Registrator 项目。它会自动注册和注销部署 Docker 容器的服务实例。 Registrator 支持多种服务注册,包括 etcd 和 Consul。

另一个例子是 NetflixOSS Prana。它主要用于用非 JVM 语言编写的服务,它是一个与服务实例并行运行的 sidecar 应用程序。 Prana 向 Netflix Eureka 注册和注销服务实例。

服务注册器是部署环境的内置组件。 Autoscaling Group 创建的 EC2 实例可以自动注册到 ELB。 Kubernetes 服务会自动注册并可供发现。

第三方注册模式有各种优点和缺点。一个主要的好处是服务与服务注册中心分离。您不需要为开发人员使用的每种编程语言和框架实现服务注册逻辑。相反,服务实例注册在专用服务中以集中方式处理。这种模式的一个缺点是,除非它内置到部署环境中,否则它是另一个需要设置和管理的高可用性系统组件。

总结

在微服务应用程序中,服务实例集是动态变化的。实例具有动态分配的网络位置,因此,为了让客户端能向其他服务发出请求,它必须使用服务发现机制。

服务发现中的关键部分是服务注册中心,而服务注册表是可用服务实例的数据库。服务注册中心提供了管理 API 和查询 API。服务实例使用管理 API 在服务注册表中注册和注销。系统组件使用查询 API 来发现可用的服务实例。

有两种主要的服务发现模式:客户端发现和服务端发现。在使用客户端服务发现的系统中,客户端查询服务注册中心、选择可用实例并发出请求。在使用服务器端发现的系统中,客户端通过查询服务注册表并将请求转发到可用实例。

服务实例在服务注册表中注册和注销的主要方式有两种。一种选择是让服务实例向服务注册中心注册自己,即自注册模式。另一种选择是让其他系统组件代表服务处理注册和注销,即第三方注册模式。

你可能感兴趣的:(深入了解服务发现)