翻译:微服务架构中的服务发现

阅读:344 2019-03-19 14:42:27 来源:新网

还是推荐大家尽量读原文。

服务发现机制并不是什么新东西了,只是随着微服务架构的流行,其变得越来越普遍和重要。本文是一片不错的介绍性文章,对于高手们来说,其中没有太多新鲜的东西。但是里面提到的大部分技术都依旧在快速地发展,时刻关注它们的变化,对于正在从事此项工作的同学来说还是很重要的。

本文介绍了服务发现的发现和注册两个机制的实现模式,其中的优缺点部分讲的我认为是比较简单的。但是在实际工作中,其方案的选择要远比这要复杂。同时,对于大规模的应用,其实现方式更倾向于多种模式的组合使用。

我在译文里加了些注释,如有错误,请多多指出。

这是应用微服务构建应用文章系列的第四篇。第一篇文章介绍微服务结构模式和讨论微服务优缺点。第二篇和第三篇是描述微服务通讯的不同方面。本系列,我们来探索与服务发现紧密相关的问题。

让我们想象一下你在一些调用rest或thrift服务的代码。为了能请求成功,你的代码需要知道服务实例的网络地址(ip和端口)。在传统的运行在物理机上的应用,服务的网络地址是相对静态的。例如,你的代码可以从偶尔更新的配置文件中读取到网络地址。

然而,在现代的基于云计算的微服务应用中,问题将变得难以解决,如下图所示:

服务实例会被动态地分配网络地址。并且,因为自动伸缩、故障和升级,服务实例会动态地改变。故而,你的客户端代码需要用一种更加精密的服务发现机制。

有两个主要的服务发现模式:客户端发现和服务端发现。让我们先来看看服务端发现。

当使用客户端发现模式的时候,客户端负有决定可用的服务实例和负载均衡之职责。客户端查询服务注册中心。所谓服务注册中心就是一个保存可用服务实例的数据库。然后,客户端使用负载均衡算法选择其中一个可用的服务实例并向其发出请求。

下图展示了这种模式的结构

当服务实例启动时,其会将自己的网络地址注册到服务注册中心。在实例销毁时删除这些信息。服务实例的注册信息会用心跳机制定期刷新。

netflixoos提供了一个非常好的客户端服务发现模式的例子。netflixeureka_(注:希腊语“我发现了”的意思)_是一个服务注册中心。提供了用于服务实例注册管理和查询可用实例的restapi。netflixribbon提供了能够和eureka配合使用的进程间通信客户端,其可以实现请求的负载均衡。我们将在稍后深入讨论eureka。

客户端发现模式有利有弊。这个模式相对直接,并且,除了服务注册中心以外,没有其它活动(moving)部分。而且,因为客户端了解可用的服务实例,因此可以实现智能的,与应用相关的负载均衡策略,例如一致性哈希。(但是其)一个明显的缺点是将客户端和服务注册中心耦合在一起_(注:其实也算不上耦合,如果用rest这样的平台无关的协议)_。你必须为你使用的每种语言和框架实现客户端发现逻辑。

现在我们已经看过了客户端发现模式,下面我们来看服务端发现模式。

另一个种服务发现的方式是服务端发现模式。如下图所示:

客户端通过负载均衡器向服务发起请求。负载均衡器查询服务注册中心,将每个请求路由到可用的服务实例上。如同客户端发现,服务实例也会在服务注册中心上注册和解注册。

awselasticloadbalancer(elb)是一个服务端发现路由的例子。elb通常用来均衡来自互联网的请求负载。当然,你也可用处理从内网到vpc的请求_(注:内部网络,可能是私有云,与aws公有云结合使用的场景)_。客户端使用elb的dns名字向elb发送请求。elb在ec2实例或ecs容器间均衡负载。这里并没有一个分离的服务注册中心。取而代之的做法是ec2和ecs直接注册到elb上。

如同nginx这样的http服务器和负载均衡器也可被用作服务器端发现中的负载均衡器。例如,这篇博文描述了使用consultemplate(注:consul类似于zookeeper和etcd但采用了更轻量的一致性算法)动态配置nginx反向代理。consultemplate会定期根据consul服务注册中的数据重新生成任意(注:任意的意思是可配)配置文件。并在文件改变的时候执行任意的命令。在这个博文的例子中,consultemplate生成nginx.conf文件,其用来配置反向代理,然后(consultemplate)运行命令告诉nginx重载配置。一个更高级的实现还能动态地使用httpapi或dns配置nginxplus(注:dns怎么配置nginx,弱弱地我表示不懂)

一些部署环境使用k8s和marathon在集群中的每一个宿主机上运行一个代理。代理起到了服务发现模式中的负载均衡器。为了使请求能到服务上,一个客户端使用宿主的ip地址和给服务分配的端口,通过代理路由请求(注:宿主ip代表代理,端口代表服务)。然后代理透明地将请求发送到这个集群中某个可用的服务实例上。

服务端发现模式有利有弊。一个最大的好处是(服务)发现的细节被从客户端抽象出来。客户端只需简单地向负载均衡器发送请求。这避免了为客户端使用的不同语言和框架实现发现逻辑。并且,就像上面所提到的那样,一些部署环境已经免费滴提供了这个功能。当然,这个模式也有一些缺点。除非部署环境提供了负载均衡器,否则你就需要建立和管理另一套高可用的提供组件。

服务注册中心是服务发现的关键部分。它是一个包含服务实例网络地址的数据库。一个服务注册中心需要保证高可用和及时更新。客户端可以缓存从服务注册中心获得的网络地址。然而,这些信息迟早会变得过时,从而使得客户端无法发现服务实例。因此,由一个集群组成的服务注册中心使用复制协议(注:paxos之类)保证一致性。

我们前面提到了,netflixeureka是一个不错的服务注册中心例子。它提供了相关的restapi。服务实例可以使用post请求注册网络地址。每30秒必须通过put请求刷新注册。一个注册可以通过httpdelete请求或超时被删除。如你所愿,客户端可以通过get请求获取注册的服务实例。

netflix通过在每个awsec2availabilityzone运行一个或多个eureka服务实现高可用。每个运行在ec2实例上的eureka服务使用一个弹性ip地址(注:一个基于dns的aws服务)。dnstext用来记录eureka集群的配置,这个配置是一个从availabilityzones到eureka服务器网络地址的映射_(注:说白了就是域名服务)_。当一个eureka服务启动,它将查询dns以获得eureka集群配置,定位自己的peers,将自己分配到一个未使用elasticip地址(注:就是dhcp呗?说的不对请纠正我)。

eureka客户-服务和服务客户端-通过查询dns发现eureka服务器的网络地址。客户端倾向使用同一个avaiabilityzonesaz中的eureka服务。然而,当同一个az中的eureka不可用时,客户端将使用其它az的eureka_(注:应该存在dns延时性的问题)_。

其它服务注册中心的例子包括_(注:spring和netflix应该是真爱)_:

如之前提到的,一些系统,如k8s、marathon和aws没有提供显式的服务注册功能。但是,事实上它们的基础服务已经内建了这项功能。

现在我们已经看到了服务注册的概念,接下来让我们来看看服务实力是如何注册的。

如前所述,服务实例在服务注册中心注册和解注册。实现这两者有两种不同的方式。其一是自行注册模式。其二是第三方注册模式,即由其他系统逐渐管理服务的注册。我们先来看前者。

当我们使用自行注册模式时,一个服务实例负有将自己注册和解注册给服务注册中心的职责。并且,如果需要,服务实例需要发送心跳请求,以防止注册过期。下图展示了这种模式的结构:

这种方法的一个例子是netflixosseurekaclient。一个eureka客户端搞定服务注册和解注册的方方面面。springcloud项目,其实现了不同的模式,包括服务发现,使得使用者可以轻松地注册服务实例进eureka。你可以简单地在javaconfiguration_(注:spring的最新配置方法,可用来替代xml配置)_类上加上@enableeurekaclientannotation。

下面说这种模式的优缺点。一个好处是它相对简单,不需要其它系统组件。然而,一个主要缺点是其耦合了服务实例和服务注册中心。你需要为你所使用的每种语言和框架写代码实现注册功能。

(注:另一个好处是可以实现更丰富的服务状态,而不只是可用、不可用这么简单的几种。还能实现比如“哎呦,还不错啊”状态。因为毕竟自己最懂自己)

下面要介绍的第三方注册模式解耦了服务和服务注册中心。

当使用第三方注册模式时,服务实例不用负责服务注册功能。取而代之的是,另一个可称为服务注册器的系统组件负责服务注册。服务注册器通过轮询或订阅事件的方式跟踪一组服务实例(状态)的改变。当服务注册器发现新的可用服务后,其将这个实例注册到服务注册中心。服务注册器也可以将销毁的实例解注册。下图展示了这种模式的结构:

服务注册器的一个例子是开源项目registrator。它自行地将以docker容器形式运行的服务注册和解注册。registrator支持多种服务注册中心,包括etcd和consul。

另一个服务注册器的例子是netflixossprana。其主要用于非jvm语言的服务,它是一个附加(sidecar,挎斗车)应用,伴随服务实例运行。prana会将服务实例注册和解注册进netflixeureka。

服务处测器是部署环境的内建组件。被awsautoscalinggroup创建的ec2实例会自动注册进elb。kubernetes服务会被自动注册使其可被发现。

优缺点环节。这种模式的主要优点是将服务实例和服务注册中心解耦。你不需要为不同语言和框架实现服务注册逻辑。取而代之的是服务注册将通过一个专门的服务,按照一种集中化的方式进行。

一个缺点是,除非部署环境内建支持,否则你需要另一个建立和管理另一个高可用的系统组件_(注:这个相对还好)_

在微服务应用中,一组运行的服务实例会动态地变化。实例可以被动态分配网络地址。因此,为了使客户端可以成功请求服务,服务发现机制是必须的。

服务发现的一个关键部分是服务注册中心。服务注册中心是一个可用服务实例的数据库。服务注册中心提供注册管理和查询的api。服务实例通过调用注册api注册和解注册。查询api用来发现可用的服务实例。

服务发现的两种模式:客户端发现和服务端发现。在一个使用客户端发现模式的系统中,客户查询服务注册信息,选择可用的服务实例,发送业务请求。在一个使用服务端发现模式的系统中,客户通过路由器发送业务请求,路由器查询服务注册信息并投递请求至可用的实例。

服务注册同样有两种方式。一是自行注册模式。另一个第三方注册模式。

在一些部署环境中,我们需要通过使用例如netflixeureka、etcd或zookeeper建立我们自己的服务发现基础架构。在另一些环境中,服务发现机制是内建的,例如k8是和marathon处理服务注册和解注册。它们同样在每个集群宿主机上运行代理,起到服务端发现模式中路由器的作用。

一个http反向代理和负载均衡器,例如nginx也可以被用来做服务端发现模式中的负载均衡器。服务注册可以推送路由信息给ngnix并更新配置。例如,你可以使用consultemplate。nginxplus支持额外的动态重配置机制-其可用来从dns拉取服务注册的信息,并提供api用于远程重配置。

下一篇: localStorage
相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>
推荐商标

{{ v.name }}

{{ v.cls }}类

立即购买 联系客服