06-分布式架构设计二(服务注册与发现)
xiangliheart
xiangliheart
发布于 2022-01-30 / 11 阅读 / 0 评论 / 0 点赞

06-分布式架构设计二(服务注册与发现)

服务注册与发现

服务注册与发现技术可以说是微服务架构核心中的核心,是服务自治的重中之重。为什么需要服务注册与发现呢?它是如何不断地演变来解决问题的呢?下面以互联网电商系统中的用户下单流程为例进行深入分析。

1.服务注册与发现面临的问题

在互联网电商系统中,微服务架构下的用户下单流程如图3-11所示。用户完成一次下单动作需要订单服务、库存服务、支付服务、用户服务、商品服务相互协作完成,它们之间均可能存在相互的调用,而每个服务都有自己的IP地址和端口,如果将每个服务的IP地址和端口都硬编码或放置在配置表中,一旦目标服务发生变化(修改IP地址或端口),则其他服务也必须进行代码修改或配置变化,稍有不慎就会造成通信中断。

图3-11 微服务架构下的用户下单流程

如图3-12所示,一旦用户服务的IP地址或端口发生变化

(10.1.22.34:8084变为10.1.22.36:8888),则与之发生调用关系的库存服务、订单服务、支付服务、商品服务都必须及时修改,否则将会导致大量请求超时,造成系统级联故障。

图3-12 用户服务的IP地址和端口发生变化的影响范围

首先想到的是可以使用Nginx进行反向代理解决IP地址和端口变化问题,架构方式如图3-13所示。将所有的服务地址都配置在Nginx上,各个服务之间的相互访问都通过Nginx进行交互,这种方式存在以下4 个缺点。

(1)     当服务的IP地址或端口发生变化时,必须手动修改和刷新

Nginx的配置。

(2)     当增加和减少服务节点时,也要修改和刷新Nginx的配置。

(3)     这种方式会让服务产生中心化,Nginx必须保证高可用,多个节点的配置文件必须保持完全相同,每次节点发生增加、减少、修改就需要维护多个节点的配置文件。

(4)     所有的服务交互都多了一步Nginx的转发,对性能会有一定的损耗。

图3-13 Nginx反向代理解决IP地址和端口变化问题

2.注册中心的原理

微服务架构是如何使用服务注册与发现技术解决这个问题的呢?服务注册与发现的原理如图3-14所示,交互过程包括以下3个步骤。

(1)     注册中心是一个独立部署的微服务,专门负责服务注册与发现。将新启动的服务节点元数据保存到注册表中,将停止或异常的服务从注册表中剔除。

(2)     当订单服务、库存服务启动时,会将自己的元数据信息,包括服务名称(order-service、storage-service)、IP地址和端口都发送给注册中心。注册中心接收到请求后,会将服务名称、IP地址和端口都保存到服务注册表中(一般采用内存存储),也可以持久化到数据库中。

(3)     当订单服务请求库存服务时,会先从注册中心获取注册表信息,查询到库存服务(storage-service)所对应的IP地址和端口(10.1.22.31:8081),然后订单服务会直接使用此IP地址和端口去访问库存服务,从而完成接口交互。

图3-14 服务注册与发现的原理

思考1:这样做有什么好处?

每个服务的信息都是动态的,就算某个服务发生了迁移,修改了 IP地址和端口,那么注册中心也会发生相应的修改,调用方无须做任何代码和配置上的修改,只需要从注册中心获取新的地址信息就可以自动适应这种变化,这就起到了服务自动注册和发现的作用。

借助注册中心,微服务就可以动态地增加和减少节点,调整服务规模,使微服务成为一种能够自我治理的弹性伸缩式架构。

思考2:如何知道微服务还存活?如何动态添加和剔除微服务?每个微服务都与注册中心之间保持着定时的心跳和同步机制,通过心跳机制注册中心可以感知到微服务是否存活,如果连续的心跳检测失败,就会将其从注册表中剔除,从而保证故障应用不会被请求到。如果过一段时间服务恢复,则还可以自动注册到注册中心,可以被重新请求到。心跳和注册表同步如图3-15所示。

图3-15 心跳和注册表同步

思考3:每次请求都要先去查询注册中心,性能不会降低吗?

每个微服务都会在本地保存一份注册表副本(内存存储),同时与注册中心保持同步或订阅关系,当注册表发生变化时,副本也能立即发生变化。当发生服务调用时,微服务会先到本地的注册表副本中查找,查找不到才会去注册中心查找,以此来提高性能和可用性,就算注册中心宕机了,各个微服务依然可以凭借本地副本继续运行。

现在主流的注册中心有Eureka、Nacos、Consul、Zookeeper等,原理都是相同的,因此完全可以根据其原理自行开发。

3.微服务与注册中心之间的操作微服务与注册中心之间存在Register(注册)、Renew(续约)、

Cancel(下线)、Get(获取)几种交互。

(1)Register(注册):微服务启动时将自身的元数据信息发送给注册中心进行存储。(2)Renew(续约):微服务要定时向注册中心发送续约请求,证明自己还存活,不要从注册表中剔除。

(3) Cancel(下线):微服务主动要求下线,将自己从注册中心的注册表中剔除。

(4) Get(获取):微服务从注册中心获取注册表信息。

4.注册中心高可用

注册中心十分重要,它属于微服务的基础设施,存储着所有微服务节点的元数据信息,必须要有较高的可用性,一旦发生宕机将导致所有微服务节点受到影响,无法动态感知整个微服务的变化。注册中心一般采用负载均衡、节点复制、选举策略保证高可用。下面以Eureka 和Consul两种注册中心服务为例进行讲解,其他注册中心与二者原理类似。

以Eureka注册中心高可用架构为例,如图3-16所示,Eureka Server 为注册中心的服务器节点,它们可以分别部署在不同的数据中心。例如,us-east-1c代表美国-东-1c数据中心,us-east-1d代表美国-东-1d数据中心。多个Eureka服务之间采用复制机制(Replicate),都存储着全部

的服务注册表信息,因此各微服务(Application Service)将自己的信

息注册到任意一个Eureka服务即可。当某个注册中心发生故障后,其他节点依然可以提供服务。

图3-16 Eureka注册中心高可用架构

以Consul注册中心高可用架构为例,如图3-17所示,Datacenter 1、Datacenter 2分别代表两个数据中心,每个机房都部署了3个Consul Server注册中心服务,3个服务之间保持着数据复制(Replication),同时使用选举算法(Leader Forwarding)组成1个Leader(主节点)和2个 Slave(从节点)的高可用架构。Datacenter 1、Datacenter 2两个数据中心之间通过互联网进行访问,从而形成了多数据中心的高可用架构。

图3-17 Consul注册中心高可用架构


评论