服务调用问题
单实例情况:可以采用点对点的 HTTP 直接调用,采用 IP + Port + 接口的形式进行。也可以对外暴露 WebService 服务供外部模块调用,但 WebService 的形式 显示比 HTTP的形式稍重一些,在实际的业务开发过程中,越来越的产品开发采用轻量级的 HTTP 协议进行数据交互。如果模块增多,将会形成蜘蛛网的形式,非常不利于开发维护。
多实例的情况:为应对服务的压力,采用多实例集群部署已成为简捷易用的解决方案。仅仅多实例部署后,直接面临一个问题,调用方如何知晓调用哪个实例,当实例运行失败后,如何转移到别的实例上去处理请求?如果采用了负载均衡,但往往是静态的,在服务不可用时,如果动态的更新负载均衡列表,保证调用者的正常调用呢?
面对以上两种情况,服务注册中心的需求迫在眉捷,将所有的服务统一的、动态的管理起来。
三种角色
在微服务架构下,主要有三种角色:服务提供者(RPC Server)、服务消费者(RPC Client)和服务注册中心(Registry)。
- RPC Server提供服务,在启动时,根据服务发布文件server.xml中的配置的信息,向Registry注册自身服务,并向Registry定期发送心跳汇报存活状态。
- RPC Client调用服务,在启动时,根据服务引用文件client.xml中配置的信息,向Registry订阅服务,把Registry返回的服务节点列表缓存在本地内存中,并与RPC Sever建立连接。
- 当RPC Server节点发生变更时,Registry会同步变更,RPC Client感知后会刷新本地内存中缓存的服务节点列表。
- RPC Client从本地缓存的服务节点列表中,基于负载均衡算法选择一台RPC Sever发起调用。
服务注册
服务注册中心作分布式服务框架的核心模块,要实现的功能是服务的注册、订阅,与之相应的功能是注销、通知这四个功能。
注册中心:在注册中心服务端,有一个用来管理服务的容器,他保存着所有服务的实例。(包括服务调用者)(底层结构是双层map、mysql数据库等)
服务发现
一般来说服务发现的完整流程,应该是先从注册中心获取到服务的实例列表,然后再根据自身的需求(负载均衡策略),来选择其中的部分实例或者按照一定的流量分配机制来访问不同的服务提供者。
服务管理过程
所有的服务都与注册中心发生连接,由注册中心统一配置管理,不再由实例自身直接调用。服务管理过程大致过程如下:
- 服务提供者启动时,将服务提供者的信息主动提交到服务注册中心进行服务注册。
- 服务调用者启动时,将服务提供者信息从注册中心下载到调用者本地,调用者从本地的服务提供者列表中,基于某种负载均衡策略选择一台服务实例发起远程调用,这是一个点到点调用的方式。
- 服务注册中心能够感知服务提供者某个实例下线,同时将该实例服务提供者信息从注册中心清除,并通知服务调用者集群中的每一个实例,告知服务调用者不再调用本实例,以免调用失败。
健康检查机制
当前主流的注册中心,对于健康检查机制主要都采用了 TTL(Time To Live)机制,即客户端在一定时间没有向注册中心发送心跳,那么注册中心会认为此服务不健康,进而触发后续的剔除逻辑。
以ZooKeeper为例,它是基于ZooKeeper客户端和服务端的长连接和会话超时控制机制,来实现服务健康状态检测的。
在ZooKeeper中,客户端和服务端建立连接后,会话也随之建立,并生成一个全局唯一的Session ID。服务端和客户端维持的是一个长连接,在SESSION_TIMEOUT周期内,服务端会检测与客户端的链路是否正常,具体方式是通过客户端定时向服务端发送心跳消息(ping消息),服务器重置下次SESSION_TIMEOUT时间。如果超过SESSION_TIMEOUT后服务端都没有收到客户端的心跳消息,则服务端认为这个Session就已经结束了,ZooKeeper就会认为这个服务节点已经不可用,将会从注册中心中删除其信息。
nacos:服务提供者会自动给注册中心上报心跳;当服务提供者的某个服务一段时间没有上报心跳时,注册中心会主动寻问服务提供者,若该服务不健康,则从注册中心删除该服务,注册中心给服务调用者更新服务列表
Nacos 提供了两种服务类型供用户注册实例时选择,分为临时实例和永久实例。(但是在 Nacos2.0 中我们将是否持久化的数据抽象至服务级别,且不再允许一个服务同时存在持久化实例和非持久化实例,实例的持久化属性继承自服务的持久化属性。)
临时实例只是临时存在于注册中心中,会在服务下线或不可用时被注册中心剔除,临时实例会与注册中心保持心跳,注册中心会在一段时间没有收到来自客户端的心跳后会将实例设置为不健康,然后在一段时间后进行剔除。
永久实例在被删除之前会永久的存在于注册中心,且有可能并不知道注册中心存在,不会主动向注册中心上报心跳,那么这个时候就需要注册中心主动进行探活。一些基础的组件例如数据库、缓存等,这些往往不能上报心跳,这种类型的服务在注册时,就需要作为持久化实例注册。
白名单机制
在实际的微服务测试和部署时,通常包含多套环境,比如生产环境一套、测试环境一套。开发在进行业务自测、测试在进行回归测试时,一般都是用测试环境,部署的RPC Server节点注册到测试的注册中心集群。但经常会出现开发或者测试在部署时,错误的把测试环境下的服务节点注册到了线上注册中心集群,这样的话线上流量就会调用到测试环境下的RPC Server节点,可能会造成意想不到的后果。
为了防止这种情况发生,注册中心需要提供一个保护机制,你可以把注册中心想象成一个带有门禁的房间,只有拥有门禁卡的RPC Server才能进入。在实际应用中,注册中心可以提供一个白名单机制,只有添加到注册中心白名单内的RPC Server,才能够调用注册中心的注册接口,这样的话可以避免测试环境中的节点意外跑到线上环境中去。
总结
注册中心可以说是实现服务化的关键,因为服务化之后,服务提供者和服务消费者不在同一个进程中运行,实现了解耦,这就需要一个纽带去连接服务提供者和服务消费者,而注册中心就正好承担了这一角色。此外,服务提供者可以任意伸缩即增加节点或者减少节点,通过服务健康状态检测,注册中心可以保持最新的服务节点信息,并将变化通知给订阅服务的服务消费者。
注册中心一般采用分布式集群部署,来保证高可用性,并且为了实现异地多活,有的注册中心还采用多IDC部署,这就对数据一致性产生了很高的要求,这些都是注册中心在实现时必须要解决的问题。
参考:
https://nacos.io/docs/ebook/ynstox/
https://www.cnblogs.com/Xianhuii/p/17112392.html
SpringCloud微服务实战
从0开始学微服务
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。