微服务架构中的服务发现

为什么使用服务发现?

我们假设您正在编写一些调用具有REST API或Thrift API的服务的代码。为了发送请求,您的代码需要知道服务实例的网络位置(IP地址和端口)。在运行在物理硬件上的传统应用中,服务实例的网络位置是相对静态的。例如,您的代码可以从偶尔更新的配置文件读取网络位置。

然而,在现代的基于云的微服务应用中,这是一个更难解决的问题,如下图所示。

服务实例具有动态分配的网络位置。此外,由于自动缩放,故障和升级,服务实例集合会动态更改。因此,您的客户端代码需要使用更精细的服务发现机制。

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

客户端发现模式

当使用客户端发现时,客户端负责确定可用服务实例的网络位置和负载均衡请求。客户端查询服务注册表,它是可用服务实例的数据库。然后,客户端使用负载均衡算法来选择一个可用的服务实例并发出请求。

下图显示了此模式的结构。

服务实例的网络位置在服务注册表启动时被注册。当实例终止时,它从服务注册表中删除。通常使用心跳机制周期性地刷新服务实例的注册。

Netflix OSS提供了客户端发现模式的一个很好的例子。 Netflix Eureka是一个服务注册表。它提供了一个用于管理服务实例注册和查询可用实例的REST API。 Netflix Ribbon是一种IPC客户端,可与Eureka一起使用,以在可用的服务实例之间进行负载均衡请求。我们将在本文后面更深入地讨论Eureka。

客户端发现模式有各种好处和缺点。这种模式是相对简单的,除了服务注册表,没有其他移动部件。此外,由于客户端了解可用的服务实例,因此可以进行智能的,特定于应用程序的负载均衡策略,例如一致性Hash。这种模式的一个重要缺点是它将客户端与服务注册表相结合。您必须为服务客户端使用的每个编程语言和框架实施客户端服务发现逻辑。

现在我们已经看过了客户端发现,那我们再来看看服务器端的发现

服务器端发现模式

服务发现的另一种方法是服务器端发现模式。下图显示了此模式的结构。

客户端通过负载均衡器向服务器发出请求。负载均衡器查询服务注册表并将每个请求路由到可用的服务实例。与客户端发现一样,服务实例可在服务注册表中进行注册和注销。

AWS弹性负载均衡器(ELB)是服务器端发现路由器的示例。 ELB通常用于负载均衡来自互联网的外部流量。但是,您还可以使用ELB来负载均衡虚拟专用云(VPC)内部的流量。客户端使用其DNS名称通过ELB发出请求(HTTP或TCP)。 ELB负载均衡一组注册的弹性计算云(EC2)实例或EC2容器服务(ECS)容器之间的流量。没有单独的服务注册表。相反,EC2实例和ECS容器在ELB本身注册。

HTTP服务器和负载均衡器(如NGINX Plus和NGINX)也可以用作服务器端发现的负载均衡器。例如,本文描述了使用Consul模板动态重新配置NGINX反向代理。Consul模板是一种工具,可以从存储在Consul服务注册表中的配置数据定期重新生成任意配置文件。每当文件更改时,它都会运行任意的shell命令。在文章描述的示例中,Consul Template生成一个nginx.conf文件,它配置反向代理,然后运行一条命令,指示NGINX重新加载配置。更复杂的实现可以使用其HTTP API或DNS动态重新配置NGINX Plus。

某些部署环境(如Kubernetes和Marathon)在群集中的每个主机上运行代理。代理扮演服务器端发现负载均衡器的角色。为了向服务发出请求,客户端通过代理使用主机的IP地址和服务的分配端口路由请求。然后,代理将请求透明地转发到在集群中某处运行的可用服务实例。

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

服务注册表

服务注册表是服务发现的关键部分。它是一个包含服务实例的网络位置的数据库。服务注册表需要高度可用和最新。客户端可以缓存从服务注册表获得的网络位置。但是,该信息最终会变得过时,客户端无法发现服务实例。因此,服务注册表由使用复制协议维护一致性的一组服务器组成。

如前所述,Netflix Eureka是服务注册表的一个很好的例子。它提供了一个用于注册和查询服务实例的REST API。服务实例使用POST请求注册其网络位置。每30秒,它必须使用PUT请求刷新其注册。通过使用HTTP DELETE请求或实例注册超时来删除注册。如您所料,客户端可以使用HTTP GET请求来检索注册的服务实例。

Netflix通过在每个Amazon EC2可用区域中运行一个或多个Eureka服务器来实现高可用性。每个Eureka服务器都运行在具有弹性IP地址的EC2实例上。 DNS TEXT记录用于存储Eureka集群配置,这是从可用性区域到Eureka服务器的网络位置列表的映射。当Eureka服务器启动时,它会查询DNS以检索Eureka群集配置,查找其对等体,并为其分配一个未使用的Elastic IP地址。

Eureka客户端 - 服务和服务客户端 - 查询DNS以发现Eureka服务器的网络位置。客户喜欢在相同的可用性区域中使用Eureka服务器。但是,如果没有可用的客户机,则在另一个可用性区域中使用Eureka服务器。

服务注册表的其他示例包括:

etcd - 用于共享配置和服务发现的高可用性、分布式、一致的键值存储。使用etcd的两个显着的项目是Kubernetes和Cloud Foundry。

consul - 发现和配置服务的工具。它提供了一个API,允许客户端注册和发现服务。consul可以进行健康检查来确定服务的可用性。

Apache Zookeeper - 分布式应用程序广泛使用的高性能协调服务。 Apache Zookeeper原来是Hadoop的一个子项目,但现在是一个顶级项目。 另外,如前所述,一些系统,如Kubernetes,Marathon和AWS没有明确的服务注册表。相反,服务注册表只是基础架构的内置部分。

现在我们已经看了一个服务注册表的概念,我们来看看服务实例如何在服务注册表中注册。

服务注册选项

如前所述,服务实例必须从服务注册表注册或注销。有几种不同的方式来处理注册和注销。一个选项是服务实例注册自己,自注册模式。另一个选项是使用某些其他系统组件来管理服务实例的注册,第三方注册模式。我们先看一下自我注册模式。

自我注册模式

当使用自注册模式时,服务实例自己负责注册到服务注册表或从注册表中注销自己。此外,如果需要,服务实例发送心跳请求,以防止其注册过期。下图显示了此模式的结构。

这种方法的一个很好的例子是Netflix OSS Eureka客户端。 Eureka客户端处理服务实例注册和注销的所有方面。实施各种模式的Spring Cloud项目,包括服务发现,可以轻松地使用Eureka自动注册服务实例。您只需使用@EnableEurekaClient注释对Java Configuration类进行注释。

自我注册模式有各种好处和缺点。一个好处是它相对简单,不需要任何其他系统组件。然而,主要的缺点是它将服务实例耦合到服务注册表。您必须在您的服务使用的每种编程语言和框架中实施注册码。

将服务与服务注册表分离的替代方法是第三方注册模式。

第三方注册模式

当使用第三方注册模式时,服务实例不负责向服务注册表注册自己。相反,称为服务注册器的另一系统组件处理注册。服务注册器通过轮询部署环境或订阅事件跟踪对运行实例集的更改。当它注意到一个新可用的服务实例时,它会向服务注册表注册该实例。服务注册商也注销终止的服务实例。下图显示了此模式的结构。

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

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

服务注册商是部署环境的内置组件。自动缩放创建的EC2实例可以自动注册到ELB。 Kubernetes服务将自动注册并提供发现。

第三方注册模式有各种好处和缺点。一个主要的好处是服务与服务注册表分离。您不需要为开发人员使用的每种编程语言和框架实现服务注册逻辑。相反,在专用服务中以集中的方式处理服务实例注册。

这种模式的一个缺点是,除非内置到部署环境中,否则它是另一个高可用性的系统组件,您需要进行设置和管理。

总结

在微服务应用程序中,运行的服务实例集会动态更改。实例具有动态分配的网络位置。因此,为了使客户端向服务发出请求,它必须使用服务发现机制。

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

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

服务实例有两种主要方式从服务注册表中注册和注销。一个选项是服务实例向服务注册表注册自己的注册模式。另一种选择是使用其他系统组件的第三方注册模式处理注册和注销。

在某些部署环境中,您需要使用Netflix Eureka,etcd或Apache Zookeeper等服务注册表设置自己的服务发现基础设施。在其他部署环境中,内置服务发现。例如,Kubernetes和Marathon处理服务实例注册和注销。他们还在扮演服务器端发现路由器角色的每个集群主机上运行代理。

HTTP反向代理和负载均衡器(如NGINX)也可以用作服务器端发现的负载均衡器。服务注册表可以将路由信息推送到NGINX,并调用优化的配置更新;例如,您可以使用Consul模板。 NGINX Plus支持额外的动态重新配置机制 - 它可以使用DNS从注册表中提取有关服务实例的信息,并为远程重新配置提供API。

原文发布于微信公众号 - IT技术精选文摘(ITHK01)

原文发表时间:2017-09-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

扫码关注云+社区

领取腾讯云代金券