微服务架构下的服务发现

编者的话】这是关于使用微服务架构创建应用系列的第四篇文章。第一篇介绍了微服务架构的模式,讨论了使用微服务架构的优缺点。第二和第三篇描述了微服务架构内部的通讯机制。这篇文章中,我们将会探讨服务发现相关问题。

为什么要使用服务发现?

我们设想一下当正在写代码时,使用了提供REST API或者Thrift API的服务,为了完成一次服务请求,代码需要知道服务实例的网络位置(IP地址和端口)。传统应用都运行在物理硬件上,服务实例的网络位置都是相对固定的。例如,代码可以从一个经常变更的配置文件中读取网络位置。

而对于一个现代的,基于云微服务的应用来说,这却是一个很麻烦的问题。其架构如图所示

服务实例的网络位置都是动态分配的,而且因为扩展,失效和升级等需求,服务实例会经常动态改变,因此,客户端代码需要使用一种更加复杂的服务发现机制。

目前有两大类服务发现模式:客户端发现和服务端发现。

我们先来来讨论一下客户端发现。

客户端发现模式

当使用客户端发现模式时,客户端负责决定相应服务实例的网络位置,并且对请求实现负载均衡。客户端从一个服务注册服务中查询,其中是所有可用服务实例的库。客户端使用负载均衡算法从多个服务实例中选择出一个,然后发出请求。

下图显示的是这种模式的架构图.

服务实例的网络位置是在启动时注册到服务注册表中,并且在服务终止时从注册表中删除。服务实例注册信息一般是使用心跳机制来定期刷新的。

Netflix OSS 提供了一种非常棒的客户端发现模式。Netflix Eureka 是一个服务注册表,为服务实例注册管理和查询可用实例提供了REST API接口。Netflix Ribbon 是一种IPC客户端,与Eureka合同工作实现对请求的负载均衡。我们会在后面详细讨论Eureka。

客户端发现模式也是优缺点分明。这种模式相对比较直接,而且除了服务注册表,没有其他改变的因素。除此之外,因为客户端知道可用服务注册表信息,因此客户端可以通过使用哈希一致性(hashing consistently)变得更加聪明,更加有效的负载均衡。

而这种模式一个最大的缺点是需要针对不同的编程语言注册不同的服务,在客户端需要为每种语言开发不同的服务发现逻辑。

我们分析过客户端发现后,再看看服务端发现。

服务端发现模式

另外一种服务发现方法就是服务端发现模式server-side discovery pattern. 下图展现了这种模式的架构图:

客户端通过负载均衡器向某个服务提出请求,负载均衡器向服务注册表发出请求,将每个请求转发往可用的服务实例。跟客户端发现一样,服务实例在服务注册表中注册或者注销。

AWS Elastic Load Balancer (ELB) 是一种服务端发现路由器的例子,ELB一般用于均衡从internet来的访问流量,也可以使用ELB来均衡VPC内部的流量。客户端使用DNS,通过ELB发出请求(HTTP或者TCP)。ELB负载均衡器负责在注册的EC2实例或者ECS容器之间均衡负载,并不存在一个分离的服务注册表,而EC2实例和ECS实例也向ELB注册。

HTTP服务和如NGINX的负载均衡器都可以被作为服务端发现均衡器。例如,这篇blog post 描述如何使用 Consul Template 来动态配置NGINX反向代理。Consul Template是周期性从存放在Consul Template注册表中配置数据重建配置文件的工具。当文件发生变化时,会运行一个命令。在如上博客中,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 achieves high availability通过在每个AWS EC2域运行一个或者多个Eureka服务实现高可用性,每个Eureka服务器都运行在拥有弹性IP地址的EC2实例上。DNS TEXT记录用于存储Eureka集群配置,其中存放从可用域到一系列Eureka服务器网络地址的列表。当Eureka服务启动时,向DNS请求接受Eureka集群配置,确认同伴位置,给自己分配一个未被使用的弹性IP地址。

Eureka客户端—服务和服务客户端—向DNS请求发现Eureka服务的网络地址,客户端首选使用同一域内的服务。然而,如果没有可用服务,客户端会使用另外一个可用域的Eureka服务。

另外一些服务注册表例子包括:

• etcd – 是一个高可用,分布式的,一致性的,键值表,用于共享配置和服务发现。两个著名案例包括Kubernetes和Cloud Foundry。

• consul – 是一个用于发现和配置的服务。提供了一个API允许客户端注册和发现服务。Consul可以用于健康检查来判断服务可用性。

• Apache Zookeeper – 是一个广泛使用,为分布式应用提供高性能整合的服务。Apache Zookeeper最初是hadoop的子项目,现在已经变成顶级项目。

另外,前面强调过,某些系统,例如Kubernetes,Marathon和AWS并没有独立的服务注册表,对他们来说,服务注册表只是一个内置的功能。

现在我们来看看服务注册表的概念,看看服务实例是如何在注册表中注册的。

服务注册选项

如前所述,服务实例必须向注册表中注册和注销,如何注册和注销也有一些不同的方式。一种方式是服务实例自己注册,也叫自注册模式(self-registration pattern);另外一种方式是为其他系统提供服务实例管理的,也叫第三方注册模式(third party registration pattern)。我们来看看自注册模式。

自注册方式

当使用self-registration pattern, 服务实例负责在服务注册表中注册和注销。另外,如果需要的话,一个服务实例也要发送心跳来保证注册信息不会过时。下图描述了这种架构:

一个很好地例子是 Netflix OSS Eureka client。Eureka客户端负责处理服务实例的注册和注销。Spring Cloud project, 实现了多种模式,包括服务发现,使得向Eureka服务实例自动注册时更容易。可以用@EnableEurekaClient注释Java配置类。

自注册模式也有优缺点。一个优点是,相对简单,不需要其他系统功能。而一个主要缺点则是,把服务实例跟服务注册表 联系起来。必须在每种编程语言和框架内部实现注册代码。

另外一个方法,不需要连接服务和注册表,则是第三方注册模式。

第三方注册模式

当使用第三方注册模式时,服务实例并不负责向服务注册表注册,而是由另外一个系统模块,叫做服务管理器,负责注册。服务管理器通过查询部署环境或订阅事件来跟踪运行服务的改变。当管理器发现一个新可用服务,会向注册表注册此服务。服务管理器也负责注销终止的服务实例。下图是这种模式的架构图。

一个服务管理器的例子是开源项目 Registrator,负责自动注册和注销被部署为Docker容器的服务实例。Reistrator支持多种服务管理器,包括etcd和Consul。

另外一个服务管理器例子是 NetflixOSS Prana,主要面向非JVM语言开发的服务,也称为附带应用(sidecar application),Prana使用Netflix Eureka注册和注销服务实例。

服务管理器是部署环境内置的模块。有自动扩充组创建的EC2实例可以自向ELB自动注册,Kubernetes服务自动注册并且对发现服务可用。

第三方注册模式也是优缺点都有。主要的优点是服务跟服务注册表是分离的,不需要为每种编程语言和架构完成服务注册逻辑,替代的,服务实例是通过一个集中化管理的服务进行管理的。

一个缺点是,除非这种服务被内置于部署环境中,否则也需要配置管理一个高可用的系统。

总结

在一个微服务应用中,服务实例运行环境是动态变化的。实例网络地址也是动态变化的,因此,客户端为了访问服务必须使用服务发现机制。

服务发现关键部分是服务注册表,也就是可用服务实例的数据库。服务注册表提供一种注册管理API和请求API。服务实例使用注册管理API来实现注册和注销。

请求API用于发现可用服务实例,相对应的,有两种主要服务发现模式:客户端发现和服务端发现。

在使用客户端发现的系统中,客户端向服务注册表发起请求,选择可用实例,然后发出服务请求

而在使用服务端发现的系统中,客户端通过路由转发请求,路由器向服务注册表发出请求,转发此请求到某个可用实例。

服务实例注册和注销主要有两类方式。一种是服务实例自动注册到服务注册表中,也就是自注册模式;另外一种则是某个系统模块负责处理注册和注销,也就是第三方注册模式。

在某些部署环境中,需要配置自己的服务发现架构,例如:Netflix Eureka, etcd, 或者 Apache Zookeeper。而在另外一些部署环境中,则自带了这种功能,例如Kubernetes and Marathon 负责处理服务实例的注册和注销。他们也在每个集群节点上运行代理,来实现服务端发现路由器的功能。

HTTP反向代理和负载据衡器(例如NGINX)可以用于服务发现负载均衡器。服务注册表可以将路由信息推送到NGINX,激活一个实时配置更新;例如,可以使用 Consul Template。NGINX Plus 支持额外的动态重新配置机制,可以使用DNS,将服务实例信息从注册表中拉下来,并且提供远程配置的API。

在未来的博客中,我们还将深入探讨微服务其它特点。可以注册NGINX邮件列表来获得最新产品更新提示。

编者的话:此篇其它博客参见如下地址:

• Introduction to Microservices

• Building Microservices: Using an API Gateway

• Inter-Process Communication in a Microservices Architecture

时间: 2024-10-11 02:52:28

微服务架构下的服务发现的相关文章

微服务架构下的数据一致性:可靠事件模式

主页:http://www.howardliu.cn/ 博客:微服务架构下的数据一致性:可靠事件模式 在<微服务架构下的数据一致性:概念及相关模式>中介绍了在微服务中实现数据一致性的三种方式,包括可靠事件模式.业务补偿模式.TCC模式.本文重点说一下可靠事件投递. 1. 可靠事件模式 可靠事件模式属于事件驱动架构,微服务完成操作后向消息代理发布事件,关联的微服务从消息代理订阅到该事件从而完成相应的业务操作,关键在于可靠事件投递和避免事件重复消费. 可靠事件投递有两个特性:1)每个服务原子性的完

Re:从 0 开始的微服务架构--(四)如何保障微服务架构下的数据一致性--转

原文地址:http://mp.weixin.qq.com/s/eXvoJew3bjFKzLLJpS0Otg 随着微服务架构的推广,越来越多的公司采用微服务架构来构建自己的业务平台.就像前边的文章说的,微服务架构为业务开发带来了诸多好处的同时,例如单一职责.独立开发部署.功能复用和系统容错等等,也带来一些问题. 例如上手难度变大,运维变得更复杂,模块之间的依赖关系更复杂,数据一致性难以保证,等等.但是办法总是比问题多,本篇文章就来介绍一下我们是如何保障微服务架构的数据一致性的. 微服务架构的数据一

从 0 开始的微服务架构:(四)如何保障微服务架构下的数据一致性

虽然已经红了很久,但是"微服务架构"正变得越来越重要,也将继续火下去.各个公司与技术人员都在分享微服务架构的相关知识与实践经验,但我们发现,目前网上的这些相关文章中,要么上来就是很有借鉴意义的干货,要么就是以高端的专业术语来讲述何为微服务架构.就是没有一个做到成熟地将技术传播出来,同时完美地照顾"初入微服务领域人员",从 0 开始,采用通俗易懂的语言去讲解微服务架构的系列.所以,我们邀请青柳云的苏槐与 InfoQ 一起共建微服务架构专题"Re:从 0 开始

如何保障微服务架构下的数据一致性

1.微服务架构的数据一致性问题 以电商平台为例,当用户下单并支付后,系统需要修改订单的状态并且增加用户积分.由于系统采用的是微服务架构,分离出了支付服务.订单服务和积分服务,每个服务都有独立数据库做数据存储.当用户支付成功后,无论是修改订单状态失败还是增加积分失败,都会造成数据的不一致. 为了解决例子中的数据一致性问题,一个最直接的办法就是考虑数据的强一致性.那么如何保证数据的强一致性呢?我们从关系型数据库的 ACID 理论说起. 关系型数据库具有解决复杂事务场景的能力,关系型数据库的事务满足

微服务架构下业务单机QPS跑不上去应从哪些角度分析

这是做应用运维老生常谈的一个事儿,经常做,今天把他总结一下. 不管什么性质的业务,吞吐量的本质是木桶原理,能跑多大量取决于木桶最短的那个板,脑袋里是不是立刻可以出现木桶的那个模型,哈哈!!换句话说,当有能力提高短板的高度时,业务的吞吐量就会有所上升,但同样有个边际效应,经过多次的优化后,当再次提高短板的成本非常非常大,而付出后提高的量很低时,那就不要较劲了,直接加服务器吧. 言归正传,先解释一下单机QPS跑不上去的现象,具体表现就是高过一个点后错误率增加.时延增大,很显然遇到短板了,那么这个短板

微服务架构下,解决数据一致性问题的实践

随着业务的快速发展,应用单体架构暴露出代码可维护性差.容错率低.测试难度大和敏捷交付能力差等诸多问题,微服务应运而生.微服务的诞生一方面解决了上述问题,但是另一方面却引入新的问题,其中主要问题之一就是:如何保证微服务间的业务数据一致性.本文将通过一个商品采购的业务,来看看在Dubbo的微服务架构下,如何通过Fescar来保障业务的数据一致性.本文所述的例子中,Dubbo 和 Fescar 的注册配置服务中心均使用 Nacos.Fescar 0.2.1+ 开始支持 Nacos 注册配置服务中心.业

微服务架构下的数据一致性:概念及相关模式

主页:http://www.howardliu.cn/ 博客:微服务架构下的数据一致性:概念及相关模式 从2014年开始,微服务逐渐进入大家的实现,被认为是下一代实现信息化的有效手段.设计到系统,其中绕不开的就是数据一致性,从本地事务,到后来的分布式事务,都能够有效的保证数据一致性.但是在微服务架构中,这两种方式都不是最好的选择. 1. 使用本地事务和分布式事务保证一致性 在传统的单击应用中,最简单.最直接.最普遍的会使用一个关系型数据库,通过关系型数据库的事务保证数据的一致性.这种事务有四个基

微服务架构下分布式事务解决方案——阿里云GTS

https://blog.csdn.net/jiangyu_gts/article/details/79470240 1 微服务的发展 微服务倡导将复杂的单体应用拆分为若干个功能简单.松耦合的服务,这样可以降低开发难度.增强扩展性.便于敏捷开发.当前被越来越多的开发者推崇,很多互联网行业巨头.开源社区等都开始了微服务的讨论和实践.Hailo有160个不同服务构成,NetFlix有大约600个服务.国内方面,阿里巴巴.腾讯.360.京东.58同城等很多互联网公司都进行了微服务化实践.当前微服务的开

微服务架构下分布式事务方案

1 微服务的发展 微服务倡导将复杂的单体应用拆分为若干个功能简单.松耦合的服务,这样可以降低开发难度.增强扩展性.便于敏捷开发.当前被越来越多的开发者推崇,很多互联网行业巨头.开源社区等都开始了微服务的讨论和实践.Hailo有160个不同服务构成,NetFlix有大约600个服务.国内方面,阿里巴巴.腾讯.360.京东.58同城等很多互联网公司都进行了微服务化实践.当前微服务的开发框架也非常多,比较著名的有Dubbo.SpringCloud.thrift .grpc等. 2 微服务落地存在的问题