功能发现提供程序主机 微服务架构下的服务发现功能

微服务架构相信大家都听说过功能发现提供程序主机,甚至有些人可能已经在实战用应用过,对它也有一定的了解了。本文主要是针对新入门的同学,比较详细地讲解了微服务架构下的服务发现,希望能对大家有所帮助。

为什么需要服务发现?

相信大家都写过代码。如果我们要写代码来调用某个服务,而这个服务提供了REST API和Thrift API接口的话,在发送调用请求的时候我们肯定要先获取服务实例的网络地址(IP地址和端口号)。对于传统的应用程序来说,因为反正都是运行在物理机上,服务实例的网络地址可以说是相对静态的。我们只需要从配置文件(而且这个配置文件很少更新)里读取到服务的网络地址就可以了。

但现在情况不一样了。目前有很多应用都采用了基于云计算的微服务架构,要想获取到某个服务实例的网络地址要麻烦得多,大家可以看看下面这个图:

服务实例的网络地址是动态分配的,而且因为有自动伸缩、失败和升级机制,该组服务实例本身也处在动态变化中。所以要想调用服务,我们的客户端代码就必须采用更为精准的服务发现机制。

目前的服务发现机制主要有客户端服务发现和服务器端的服务发现两种模式,下面我先来讲客户端服务发现模式。

客户端服务发现模式

在客户端服务发现模式下,服务实例的网络地址以及实例之间的负载均衡请求都是由客户端程序确定的。客户端程序会在Service (一种数据库)中进行查询,然后根据负载均衡算法来选择可用的服务实例,并向其发出调用请求。

客户端服务发现模式的架构如下图所示:

服务实例在启动时,其网络地址就会写入Service ,直到实例终止时才会从注册表里面删去。一般情况下我们都会采用心跳机制对服务实例的注册信息进行定时刷新。

招商银行个人银行(专业版)提供哪些具体功能_功能发现提供程序主机_主机未提供3d支持

说到客户端发现模式,就必须说下Netflix OSS项目,这个项目的服务器端发现是做的比较好的。Netflix OSS的Netflix Eureka提供了REST API接口,用来实现服务实例注册管理和可用实例查询功能。Netflix Ribbon则是IPC客户端,和Eureka协同工作,实现了在可用服务实例之间发送负载均衡请求。关于Eureka的详情我们稍后再来说。

说起来,客户端发现模式有它自己的优点,但是也有很多缺点。这种模式相对简单,除了Service 之外,其他组件都是固定不变的。另外,因为客户端可以获取到可用的服务实例列表,我们就可以通过一致性哈希算法之类的技术来实现针对特定应用的智能化负载均衡。在缺点方面,客户端服务发现模式有一个很大的毛病就是Service 和客户端是耦合在一起的。对于服务客户端所采用的每一种编程语言、每一种架构,我们都要分别实现一套客户端服务发现逻辑,这种做法其实并不是很经济。

客户端服务发现模式差不多就是这样,下面我再给大家讲下服务器端的服务发现模式。

服务器端发现模式

服务发现还有一种方式,就是服务器端发现模式,具体架构如下图所示:

客户端通过负载均衡器向服务发送请求,负载均衡器在Service 中进行查找,并将各个调用请求发送给可用的服务实例。跟客服端服务发现模式一样,服务实例也会在Service 中进行注册和注销。

举个例子,AWS弹性负载均衡器(ELB)就是一个服务器端的服务发现路由器,常用于对互联网进来的外部流量实现负载均衡。当然,用户也可以通过ELB实现虚拟私有云(VPC)内部的流量负载均衡。这个过程是这样的:客户端通过ELB的DNS名称,向ELB发送HTTP或TCP请求,ELB根据负载均衡算法,在已注册的弹性计算云(EC2)服务实例或EC2容器服务(ECS)容器之间实现流量分摊。在这种机制下是没有单独的Service 的,EC2实例和ECS容器都是直接在ELB中注册。

像NGINX Plus和NGINX之类的HTTP服务器和负载均衡器也可以用来做服务器端服务发现的负载均衡器。举个例子,现在有些网络平台是通过Consul 来实现NGINX反向代理的动态重新配置的。所谓Consul 其实是一种工具,可以从存储在Consul中的配置数据定时生成任意配置文件。只要文件发生了改变,Consul 都会运行一个 command。在网络平台提交post请求的时候,Consul 就会生成一个包含反向代理设置的nginx.conf文件,然后再运行一条命令,让NGINX重新加载配置。当然也有更复杂的实现方式,比方说我们也可以通过HTTP API 或DNS来实现NGINX Plus的动态重新配置。

招商银行个人银行(专业版)提供哪些具体功能_功能发现提供程序主机_主机未提供3d支持

有些部署环境,比如和这些,会在集群中的每台主机上都跑一个代理程序。在这种情况下,代理程序其实就是服务器端服务发现的负载均衡器。客户端对服务发起调用请求的时候,会根据主机的IP地址,通过代理程序来指定请求的转发路径,然后代理程序再将调用请求发给集群内部某个可用的服务实例,这个过程是透明的。

服务器端发现模式也有优缺点。这种模式的一大好处在于,服务发现的细节已经从客户端抽象出来了,在这种模式下客户端只负责向负载均衡器发送请求。这样我们就不用针对客户端采用的每一种编程语言、每一种框架分别实现服务发现逻辑了。而且有些部署环境还免费提供服务器端的服务发现功能。当然这种模式也有一些缺点,比方说,

如果部署环境没有提供负载平衡器的话,那我们就只好自己来进行设置和管理,但是管理这种高可用性的系统组件是很麻烦的一件事情。

Service

作为服务发现的关键部分,Service 其实就是一个数据库,里面包含了所有服务实例的网络地址。这里要说一下,Service 必须具备高可用性,而且要时刻保持更新。虽然客户端可以将自身从Service 读取的网络地址缓存起来,但这些缓存信息最终肯定是会过时的,这样客户端就无法再访问服务实例了。所以,Service 必须包含一组服务器集群,这些服务器都遵循复制协议,这样才能保证一致性。

前面我们说过,Netflix Eureka在Service 方面是做的比较好的,它提供了REST API,可以对服务实例进行注册和查询。服务实例发起POST请求的时候,其网络地址就记录在Service 里面了,然后每隔30秒这个实例就要发送一个PUT请求去刷新一下自己的注册信息。实例可以通过发送HTTP DELETE请求来删除注册信息,在注册信息超时的时候,也会被自动删除。说到这里大家可能都知道了,客户端是可以通过HTTP GET请求来对已注册的服务实例进行检索的。

那么Netflix的高可用性是怎么实现的呢?在Amazon EC2的每个可用区,Netflix都运行了至少一台Eureka服务器。每台Eureka服务器都运行在一个EC2实例上,而每个EC2实例用的都是弹性IP。Eureka集群的配置信息存储在DNS TEXT中,而后者其实是一个映射表,存储了Amazon EC2可用区和Eureka服务器网络地址列表之间的映射关系。Eureka服务器启动后,它首先会进行DNS查询以获取Eureka集群的配置信息并对其他服务器进行定位,然后给自己分配一个未使用的弹性IP地址。

Eureka服务器网络地址的查询过程这样的,首先Eureka客户端向服务发送请求,然后服务客户端进行DNS查询,最后获取到Eureka服务器的网络地址。客户端首先会选择处在同一可用区的Eureka服务器,如果在同一可用区内没有可用的服务器,客户端就会转而访问位于另一可用区的Eureka服务器。

招商银行个人银行(专业版)提供哪些具体功能_主机未提供3d支持_功能发现提供程序主机

再举几个服务注册方面的例子,大家感兴趣的话可以多了解下:

·etcd– etcd是一个具有高可用性和一致性的分部式键值存储系统,主要用于共享配置和服务发现。目前业界两大巨头和Cloud Foundry使用的都是ETCD。

·consul – 这是一个用于服务发现和服务配置的工具,客户端可以通过consul提供的API来实现注册和服务发现。consul还具有health check的功能,可以用来确定服务的可用性。

·Apache – 这个太有名了,是一个针对大型分布式系统的高效协调系统,目前已经得到了非常广泛的使用。Apache 最初只是Hadoop的一个子项目,但现在已经是Hadoop重点发展的项目了。

另外,前面我们说过,有些系统比如说, 和AWS之流并没有单独提供服务注册功能,在这些系统中服务注册只是一个内置的功能,是基础架构的组成部分。

说了这么多,大家应该对服务注册有个大概的印象了吧?下面我重点讲讲服务实例是怎么注册的。

服务注册的实现方式

前面说过,服务实例必须在Service 里面进行注册和注销,这里要说的是,服务实例的注册和注销有几种不同的实现方式。其中一种是自注册模式,即服务实例自己对自己进行注册,另一种主要是用其他一些系统组件来管理服务实例的注册行为,又叫第三方注册模式。下面我会挨个讲解这两种模式。

功能发现提供程序主机_主机未提供3d支持_招商银行个人银行(专业版)提供哪些具体功能

自注册模式

在自注册模式下,服务实例在Service 中的注册和注销都是由实例本身完成的。在必要的情况下服务实例还会发送心跳包以防止其注册信息过期。这种模式的具体架构如下图所示:

Netflix OSS Eureka客户端采用的就是这种模式,服务实例的注册和注销全都由Eureka客户端完成。Netflix OSS采用了Spring Cloud工具集(Spring Cloud实现了包括服务发现在内的多种模式),所以对Eureka客户端来说,搞定服务实例的自动注册就是分分钟的事情,用户只需要用@来注释一下Java配置类就可以了。

自注册模式的优缺点:优点是它比较简单,也不需要其它的系统组件。但是自注册模式有一个很大的缺点,在这种模式下,服务实例和Service 是耦合的。开发人员必须针对服务所涉及的每一种开发语言、每一种框架写一套注册代码。

在这方面第三方注册模式要优于自注册模式,这种模式实现了服务和Service 的解耦合。

第三方注册模式

在第三方注册模式下,服务实例在Service 中的注册不再由实例自身来完成,而是由另外的系统组件来处理,这种组件又叫做服务注册器。服务注册器通过对查询部署环境或监听事件,实现了对运行中的服务实例的跟踪监测。当服务注册器发现新的可用服务实例时,就会在Service 中对该实例进行注册。另外注册器也会对已经终止的服务实例进行注销,具体架构如下图所示:

开源项目就是一种服务注册器。该项目可以对部署在Docker容器中的服务实例进行自动注册和注销,而且还支持etcd 和Consul等好几种服务注册工具。Netflix 也是一种服务注册器。Prana一开始主要是用于非JVM语言开发的服务功能发现提供程序主机,不过现在已经成了一种附加应用,可以和服务实例一同运行。Prana可以在Netflix Eureka中对服务实例进行注册和注销。

招商银行个人银行(专业版)提供哪些具体功能_主机未提供3d支持_功能发现提供程序主机

上面这些服务注册器都是部署环境的内置组件。ELB负载均衡器可以对Auto scaling群组创建的EC2实例进行自动注册,比如说对服务进行自动注册,然后服务发现功能就可以发现该项服务。

第三方注册模式的优缺点:这种模式最大的优点就是服务和复合注册表示解耦合的。服务实例的注册是由专门的注册器统一集中处理的,这样开发人员可以不必针对每一种开发语言和每一种框架分别实现服务注册逻辑了。

第三方注册模式也有缺点,比方说,如果部署环境没有内置服务注册器的话,那我们就只好自己来进行设置和管理,但是管理这种高可用性的系统组件是很麻烦的一件事情。

总结

本文的内容有点多,为帮助大家理解,下面我摘几个要点总结一下:

在基于微服务架构的应用中,运行的服务实例往往处在动态变化中,实例的网络地址也是动态分配的。所以客户端必须通过服务发现机制才能调用服务。

Service 是服务发现机制的重要组成部分,是一个存储了可用服务实例的数据库。Service 提供了两个API接口,一个用于管理,一个用于查询。服务实例在Service 中的注册和注销都是通过管理API接口来完成的,而查询API接口主要是和系统组件进行对接,以实现可用服务实例的发现功能。

服务发现主要有客户端服务发现和服务器端服务发现两种模式。在遵循客户端服务发现模式的系统中,客户端先对Service 进行查询,然后选择一个可用的实例并发送请求。在采用服务器端服务发现模式的系统中,客户端的请求是通过路由器发送的,路由器会对Service 进行检索,并将客户端的请求转发给可用的实例。

服务实例的注册与注销主要有两种方式:一种是自注册模式,即由服务实例自己对自己进行注册,另一种第三方注册模式,即由其他的系统组件对服务进行注册和注销。

在有些部署环境中,服务发现功能是内置的。比方说和就提供了服务实例的注册和注销功能,这两个系统在集群的每台主机上都设置了代理程序,提供了服务器端的发现路由功能。但是也有一些部署环境没有提供这个功能,这种情况下我们只能通过Netflix Eureka、etcd和Apache 之类的服务注册工具来搭建服务发现架构。

HTTP反向代理和NGINX之类的负载平衡器也可以用作服务器端服务发现的负载均衡器。比方说,Consul 之类服务注册工具可以将路由信息推送到NGINX并触发配置更新,而NGINX Plus则支持额外的动态重新配置机制,它可以通过DNS读取注册表中的服务实例信息,还可以为远程重新配置提供API接口。返回搜狐,查看更多

在线咨询