Go语言高并发与微服务实战 - 学习笔记


文章目录

  • Go语言高并发与微服务实战 - 学习笔记
  • 第6章 服务注册与发现
  • 6.1 服务注册与发现的基本原理
  • 6.1.1 服务注册与发现中心的职责
  • 6.1.2 服务实例注册服务信息
  • 6.1.3 CAP原理


第6章 服务注册与发现

在单体应用向微服务架构演进的过程中,原本的单体应用会按照业务需求被拆分成多个微服务,每个服务提供特定的功能,并可能依赖于其他的微服务。

每个微服务实例都可以动态部署,服务实例之间的调用通过轻量级的远程调用方式(HTTP、消息队列等)实现,它们之间通过预先定义好的接口进行访问。

由于微服务实例是动态部署,每个服务实例的地址和服务信息都可能动态变化,势必需要一个中心化的组件对各个服务实例的信息进行管理,该组件管理各个部署好的服务实例元数据,包括但不限于服务名、IP地址、Port、服务描述、服务状态等。

服务的调用方在请求某个微服务时会首先向中心化组件请求该微服务的服务实例列表,配合客户端负载均衡组件选择依赖微服务的具体实例发起调用,这就是服务发现

服务注册是指服务实例在启动时主动将自身的元数据发送到中心化组件,并与中心化组件维持心跳,维持本服务实例在线的状态;服务实例也会监控自身实例信息变化,在服务实例发生变化时报告至中心化组件以更新服务实例状态信息。

6.1 服务注册与发现的基本原理

顾名思义,服务注册与发现主要包含两部分:服务注册与服务发现。

  • 服务注册是指服务实例启动时将自身信息注册到服务注册与发现中心,并在运行时通过心跳等方式向服务注册与发现中心汇报自身服务状态;
  • 服务发现是指服务实例向服务注册与发现中心获取其他服务实例信息,用于进行随后的远程调用。
6.1.1 服务注册与发现中心的职责

在传统单体应用中,应用都是部署在固定的物理机器或者云平台上,它们之间的调用一般是通过固定在代码内部或者配置文件中的服务地址和端口直接发起。

由于应用数量较少,系统结构复杂度不高,开发人员和运维人员可以较为轻松地进行管理和配置。

随着应用架构向微服务架构迁移,微服务数量的增加和动态部署动态扩展的特性,使得服务地址和端口在运行时是随时可变的。

对此,我们需要额外的中心化组件统一管理动态部署的微服务应用的服务实例元数据,一般称它为服务注册与发现中心。

服务注册与发现中心主要有以下的职责:

  • (1)管理当前注册到服务注册与发现中心的微服务实例元数据信息,包括服务实例的服务名、P地址、端口号、服务状态和服务描述等。
  • (2)与注册到服务注册与发现中心的微服务实例维持心跳,定期检查注册表中的服务实例是否在线,并剔除无效服务实例信息。
  • (3)提供服务发现能力,为调用方提供服务提供方的服务实例元数据。

通过服务注册与发现中心,可以很方便地管理系统中动态变化的服务实例信息。正是这样的关键地位,让它也可能成为系统的瓶颈和故障点。因为服务之间的调用信息来自于服务注册与发现中心,当它不可用时,服务之间的调用可能无法正常进行。

因此服务注册与发现中心一般会多实例部署,保证其高可用性和高稳定性。

6.1.2 服务实例注册服务信息

仅有服务注册与发现中心是不够,还需要各个服务实例的鼎力配合,只有这样,整个服务注册与发现体系才能良好运作。

一个服务实例需要完成以下的事情:

  • (1)在服务启动阶段,提交自身服务实例元数据到服务注册与发现中心,完成服务注册。
  • (2)在服务运行阶段,定期和服务注册与发现中心维持心跳,保证自身在线状态。如果可能,还会检测自身元数据的变化,发生变化时重新提交数据到服务注册与发现中心。
  • (3)在服务关闭时,向服务注册与发现中心发出下线请求,注销自身在注册表中的服务实例元数据。
6.1.3 CAP原理

在本质上来讲,微服务应用属于分布式系统的一种落地实践,而分布式系统最大的难点是处理各个节点之间数据状态的一致性。

即使是倡导无状态的HTTP RESTful API请求,在处理多服务实例情况下的修改数据状态请求时,也是需要通过数据库或者分布式缓存等外部系统维护数据的一致性。

CAP原理是描述分布式系统下节点数据同步的基本定理

CAP定理由加州大学的Eric Brewer教授提出,它们分别指Consistency(一致性)、Availability(可用性)和Partition tolerance(分区容忍性)。Eric Brewer认为,以上3个指标不可能同时满足,我们来分析一下这3个指标。

黑马老师也讲过

  1. Consistency,指数据一致性,表示系统的数据信息(包括备份数据)在同一时刻都是一致的。在分布式系统下,同一份数据可能存在于多个不同的实例中,在数据强一致性的要求下,对其中一份数据的修改必须同步到它的所有备份中。在数据同步的任何时候,都需要保证所有对该份数据的请求将返回同样的状态。
  2. Availability,指服务可用性,要求服务在接受到客户端请求后,都能够给出响应。服务可用性考量的是系统的可用性,要求系统在高并发和部分节点宕机的情况下,系统整体依然能够响应客户端的请求。
  3. Partition tolerance,指分区容忍性。分布式系统中,不同节点之间通过网络进行通信。基于网络的不可靠性,位于不同网络分区的服务节点可能会通信失败,如果系统能够容忍这种情况,说明它是满足分区容忍性特性的。如果系统不能够满足分区容忍性,那么将会限制分布式系统的扩展性,即服务节点的部署数量和地区将会受限,违背了分布式系统设计的初衷,所以一般来讲分布式系统都会满足分区容忍性。

在满足了分区容忍性的前提下,分布式系统就不能同时满足数据一致性和服务可用性。

假设服务A现在有两个实例A1和A2,它们之间的网络通信出现了异常,基于分区容忍性,这并不会影响A1和A2独立的正常运行。若此时客户端请求A1,请求将数据B从B1状态修改为B2,由于网络的不可用,数据B的修改并不能通知到实例A2。如果此时另一个客户端向A2请求数据B,如果A2返回数据B1,将满足服务可用性,但并不能满足数据一致性:如果A2需要等待A1的通知之后才能够返回数据B的正确状态,虽然满足了数据一致性,但无法响应客户端请求,违背了服务可用性的指标。

基于分布式系统的基本特质,分区容忍性是必须要满足的,接下来需要考虑满足数据一致性还是服务可用性,这要取决于具体的应用场景。在类似银行对金额数据要求强致性的系统中,要优先考虑满足数据一致性:而类似大众网页的系统,用户对网页版本的新旧不会有特别的要求,在这种场景下服务可用性高于数据一致性。