微服务学习笔记-注册中心如何落地

一、注册中心如何存储服务信息

 注册中心用来存储服务信息,服务信息春初节点信息(IP和端口)、请求失败时重试的次数、请求结果是否压缩等信息。服务信息通常用JSON字符串来存储,包含多个字段,每个字段代表不同的含义。

服务一般分为多个不同的分组,每个分组的目的不同。主要集中分组方式:

  • 核心与非核心,从业务的核心程度来分。
  • 机房,从机房的维度来分。
  • 线上环境与测试环境,从业务场景维度来区分。

所以注册中心存储的服务信息一般包含三部分内容:分组、服务名以及节点信息,节点信息又包括节点地址和几点其他信息。

注册中心中获取的信息结构大致如图,具体存储的时候,按照”服务-分组-节点信息“三层结构来存储。

  • Service代表服务的具体分组
  • Cluster代表服务的接口名
  • 节点信息用KV存储

 

二、注册中心如何工作

 注册中心主要分为四个流程:

  • 服务提供者注册流程
  • 服务提供者反注册流程
  • 服务消费者查询流程
  • 服务消费者订阅变更流程

1、如何注册节点

 

服务注册流程主要几个步骤: 

  • 首先查看要注册得节点是否在白名单内?如果不在就抛出异常,在的话继续下一步。
  • 其次要查看注册得Cluster(服务的接口名)是否存在?如果不存在就抛出异常,存在的话就继续下一步。
  • 然后要检查Service(服务的分组)是否存在?如果不存在则抛出异常,存在的话继续下一步。
  • 最后将节点信息添加到对应的Service和Cluster下面的存储中。

2、如何反注册

 

服务提供者节点反注册的流程图,节点反注册流程主要包含几个步骤: 

  • 查看Service(服务的分组)是否存在,不存在就抛出异常,存在就继续下一步。
  • 查看Cluster(服务的接口名)是否存在,不存在就抛出异常,存在就继续下一步。
  • 删除存储中Service和Cluster下对应的节点信息。
  • 更新Cluster的sign值。

3、如何查询节点信息

 

服务消费者从注册中心查询服务提供者的节点信息,主要步骤:

  • 首先从loaclcache(本机内存)中查找,如果没有就继续下一步。这里为什么服务消费者要把服务信息存在本机内存呢?主要时因为服务节点信息并不总是时刻变化的,并不需要每一次服务调用都要调用注册中心获取最新的节点信息,只需要在本机内存中保留最新的服务提供者的节点列表就可以。
  • 接着从snapshot(本地快照)中查找,如果没有就继续下一步。这里为什么服务消费者要在本地磁盘存储一份服务提供者的节点信息的快照呢?这是因为服务消费者同注册中心之间的网络不一定总是可靠的,服务消费者重启时,本地内存中还不存在服务提供者的节点信息,如果此时调用注册中心失败,那么服务消费者就拿不到服务节点信息,也就没法调用。本地快照就是为了防止这种情况的发生,即使服务消费者重启后请求注册中心失败,依然可以读取本地快照,获取到服务节点信息。

4、如何订阅服务变更

 

服务消费者订阅服务提供者的变更信息,主要分为几个步骤:

  •  服务消费者从注册中心获取了服务的信息后,就订阅了服务的变化,会在本地保留Cluster的sign值。

  • 服务消费者每个一段时间,调用getSign()函数,从注册中心获取服务端该Cluster的sign值,并与本地保留的sign值做对比,如果不一致,就从服务端拉去新的节点信息,并更新localcache和snapshot。

三、注册与发现的几个问题

1、多注册中心

 理论上对于一个服务消费者来说,同一个注册中心交互是最简单的。但是不可避免的是,服务消费者可能订阅了多个服务,多个服务可能是由多个业务部门提供的,而且每个业务部门都有自己的注册中心,提供的服务只在自己的注册中心里有记录。这样的话,就要求服务消费者要具备在启动时,能够从多个注册中心订阅服务的能力。

还有一种情况是,一个服务提供者提供了某个服务,可能作为静态服务对外提供,有可能又作为动态服务对外提供,这两个服务部署在不同的注册中心,所以要求服务提供者在启动的时候,要能够同时向多个注册中心注册服务。

也就是说,对于服务消费者来说,要能够同时从多个注册中心订阅服务;对于服务提供者来说,要能够同时向多个注册中心注册服务。

2、并行订阅服务

 通常一个服务消费者订阅了不止一个服务,一个服务消费者订阅了几十个不同的服务,每个服务都有自己的方法列表以及节点列表。服务消费者在服务启动时,会加载订阅的服务配置,调用注册中心的订阅接口,获取每个服务的节点列表并初始化连接。

最开始采用了串行订阅的方式,每订阅一个服务,服务消费者调用一次注册中心的订阅接口,获取这个服务的节点列表并初始化连接,总共需要执行几十次这样的过程。在某些服务节点的初始化连接过程中,出现连接超时的情况,后续所有的服务节点的初始化连接都需要等待它完成,导致服务消费者启动变慢,最后耗费了将近五分钟时间来完成所有服务节点的初始化连接过程。

后来我们改成了并行订阅的方式,每订阅一个服务就单独用一个线程来处理,这样的话即使遇到个别服务节点连接超时,其他服务节点的初始化连接也不受影响,最慢也就是这个服务节点的初始化连接耗费的时间,最终所有服务节点的初始化连接耗时控制在了 30 秒以内。

3、批量反注册服务

 通常一个服务提供者节点提供不止一个服务,所以注册和反注册都需要多次调用注册中心。在与注册中心的多次交互中,可能由于网络抖动、注册中心集群异常等原因,导致个别调用失败。对于注册中心来说,偶发的注册调用失败对服务调用基本没有影响,其结果顶多就是某一个服务少了一个可用的节点。但偶发的反注册调用失败会导致不可用的节点残留在注册中心中,变成“僵尸节点”,但服务消费者端还会把它当成“活节点”,继续发起调用,最终导致调用失败。

以前我们的业务中经常遇到这个问题,需要定时去清理注册中心中的“僵尸节点”。后来我们通过优化反注册逻辑,对于下线机器、节点销毁的场景,通过调用注册中心提供的批量反注册接口,一次调用就可以把该节点上提供的所有服务同时反注册掉,从而避免了“僵尸节点”的出现。

4、服务变更信息增量更新

 服务消费者端启动时,除了会查询订阅服务的可用节点列表做初始化连接,还会订阅服务的变更,每隔一段时间从注册中心获取最新的服务节点信息标记 sign,并与本地保存的 sign值作比对,如果不一样,就会调用注册中心获取最新的服务节点信息。

一般情况下,按照这个过程是没问题的,但是在网络频繁抖动时,服务提供者上报给注册中心的心跳可能会一会儿失败一会儿成功,这时候注册中心就会频繁更新服务的可用节点信息,导致服务消费者频繁从注册中心拉取最新的服务可用节点信息,严重时可能产生网络风暴,导致注册中心带宽被打满。

为了减少服务消费者从注册中心中拉取的服务可用节点信息的数据量,这个时候可以通过增量更新的方式,注册中心只返回变化的那部分节点信息,尤其在只有少数节点信息变更时,此举可以大大减少服务消费者从注册中心拉取的数据量,从而最大程度避免产生网络风暴。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值