RPC实战与核心原理——进阶篇1

195 阅读5分钟

七、  架构设计

其实 RPC 就是把拦截到的方法参数,转成可以在网络中传输的二进制,并保证在服务提供方能正确地还原出语义,最终实现像调用本地一样地调用远程的目的。

RPC架构

可扩展RPC架构

八、  服务发现

为了高可用,在生产环境中服务提供方都是以集群的方式对外提供服务,集群里面的这些 IP 随时可能变化,我们也需要用一本“通信录”及时获取到对应的服务节点,这个获取的过程我们一般叫作“服务发现”。

服务注册:在服务提供方启动的时候,将对外暴露的接口注册到注册中心之中,注册中心将这个服务节点的 IP 和接口保存下来。

服务订阅:在服务调用方启动的时候,去注册中心查找并订阅服务提供方的 IP,然后缓存到本地,并用于后续的远程调用。

8.1 为什么不用DNS和VIP

8.1.1 为什么不用DNS

如果用 DNS 来实现服务发现,所有的服务提供者节点都配置在了同一个域名下,调用方的确可以通过 DNS 拿到随机的一个服务提供者的 IP,并与之建立长连接,这看上去并没有太大问题,但在业界很少用这种方案呢?主要有两个问题:

  • 如果这个 IP 端口下线了,服务调用者不能摘除服务节点;

  • 如果对这个服务进行扩容,那么新上线的服务节点不能及时接收到流量;

这是因为为了提升性能和减少 DNS 服务的压力,DNS 采取了多级缓存机制,一般配置的缓存时间较长,特别是 JVM 的默认缓存是永久有效的,所以说服务调用者不能及时感知到服务节点的变化。

8.1.2 为什么不用VIP方案

主要原因:

  • 搭建负载均衡,需要额外成本;

  • 请求流量都经过负载均衡设备,多经过一次网络传输,额外浪费性能;

  • 负载均衡增加或摘除节点,一般都要手动添加,手动添加可能会延迟

  • 负载均衡算法满足不了更加灵活的需求

8.2 基于ZooKeeper服务发现

搭建一个 ZooKeeper 集群作为注册中心集群,服务注册的时候只需要服务节点向 ZooKeeper 节点写入注册信息即可,利用 ZooKeeper 的 Watcher 机制完成服务订阅与服务下发功能,整体流程如下图:

Zookeeper本身存在性能问题。当连接到 ZooKeeper 的节点数量特别多,对 ZooKeeper 读写特别频繁,且 ZooKeeper 存储的目录达到一定数量的时候,ZooKeeper 将不再稳定,CPU 持续升高,最终宕机。而宕机之后,由于各业务的节点还在持续发送读写请求,刚一启动,ZooKeeper 就因无法承受瞬间的读写压力,马上宕机。

8.3 基于消息总线的最终一致性的注册中心

ZooKeeper 的一大特点就是强一致性,ZooKeeper 集群的每个节点的数据每次发生更新操作,都会通知其它 ZooKeeper 节点同时执行更新。它要求保证每个节点的数据能够实时的完全一致,这也就直接导致了 ZooKeeper 集群性能上的下降。

基于注册中心的特点,可以牺牲掉CP(强一致性),而选择AP(最终一致性),来换取整个注册中心集群的性能和稳定性。

通过消息总线的方式,我们就可以完成注册中心集群间数据变更的通知,保证数据的最终一致性,并能及时地触发注册中心的服务下发操作。

服务调用方拿到的服务节点不是最新的,所以目标节点存在已经下线或不提供指定接口服务的情况,这个时候有没有问题?这个问题我们放到了 RPC 框架里面去处理,在服务调用方发送请求到目标节点后,目标节点会进行合法性验证,如果指定接口服务不存在或正在下线,则会拒绝该请求。服务调用方收到拒绝异常后,会安全重试到其它节点。

九、  健康检测

心跳机制: 服务调用方每隔一段时间定时访问服务提供方获取节点的状态。

当可用率低于某个比例就认为节点存在问题。

十、  路由策略

10.1 为什么选择路由策略

服务变更上线,采用线上灰度,首先将少量的请求转发到新上线的实例上面,进行观察,根据观察的情况,选择发布更多实例还是回滚。

10.2 如何实现路由策略

IP路由

参数路由

十一、  负载均衡

11.1 RPC 框架中的负载均衡

RPC 的负载均衡完全由 RPC 框架自身实现,RPC 的服务调用者会与“注册中心”下发的所有服务节点建立长连接,在每次发起 RPC 调用时,服务调用者都会通过配置的负载均衡插件,自主选择一个服务节点,发起 RPC 调用请求。

11.2 自适应负载均衡

自适应的负载均衡,其关键点就是调用端收集服务端每个节点的指标数据,再根据各方面的指标数据进行计算打分,最后根据每个节点的分数,将更多的流量打到分数较高的节点上。

极客时间《RPC实战与核心原理》学习笔记 Day10