前言
RPC的概念看过很多,我的理解是:调用端获取到服务(网络方法)提供者的网络地址,并把方法调用的参数
通过网络传递给提供者,提供者监听并获取到参数后,调用自己的方法,再把执行结果通过网络回传给调用端。
这样站在调用端的角度看,就像是调用自己的本地方法一样,只不过慢一些而已。
RPC经典的架构图如下:
RPC架构中可以认为有四个角色,消费者(Consumer),提供者(Provider),注册中心(Registry)和
监控中心(Monitor)。以前在同一系统里的方法调用者因为网络的存在,变成了消费者,被调的方法成为了
提供者。而所谓的注册中心,其实就是为了让消费者实时的去感知提供者的存在,去告诉消费者它对应的提供
者的地址。监控中心,其实在整个过程中,它并不是一定要存在,只是它可以做统计,做一些数据分析,提供
整个系统的可用性,健壮性。
好了,我们先简单分析一下 Registry / Consumer / Provider / Monitor 这四个角色的定义和每个
角色如何各司其职,相互协作完成这整个过程的。
下面从两个方面进行分析,一是每个角色在网络的定位,二是每个角色所要完成的职责。
Registry注册中心
简述:
- 注册中心可以有多个,都是无状态的,每个注册中心之间信息不交互
- 从网络的角度来说,它都是server端,它不需要主动地连接其他的任何实例,只需要像一个地主一样等待别人来连接
- 消费者随机选择注册中心集群中的任何实例建立长连接,提供者与注册中心中的每一个实例都建立长连接
职责(与其说职责,还不如说代码要实现的功能):
- 接收服务提供者的服务注册信息,接收到信息之后,发送ACK信息给服务提供者,否则服务提供者重新发送注册信息
- 接收消费者的订阅信息,并把它订阅的结果返回给消费者
- 如果注册信息变更,会主动通知订阅变更信息的消费者,注册信息的变更包括服务提供者下线,服务被人工降级,或者服务提供者的地址变更
- 持久化一些服务信息,例如某些服务管理员审核过了,则该服务重新注册后则不需要再审核,再例如,某个服务负载均衡的策略被管理员设置为轮询,那么下次它在注册的时候,则就是轮询,而不是默认的负载策略
Provider提供者
简述:
提供者是一个精神分裂的病人,它在网络上(可以更加明确地说是站在Netty的角度上)饰演两个角色:
- 它是客户端,需要去连接Registry,发送注册信息,它也需要去连接monitor端,去发送一些调用的统计信息
- 它也是服务端,需要作为server端等待Consumer去连接,连接成功后调用服务
职责:
- 将自己的信息,提供的接口信息编织成注册信息发送给registry端
- 能够动态去调自己的方法,可以通过反射,cglib等一些方法去调用自己提供的那些方法
- 提供服务降级等服务,如果当某些服务调用的失败率高于限定值的时候,可以有一个对应的mock方法,提供降级服务
- 限流服务,限流的方式有很多种,也有很多实现方式,最简单的就是控制调用次数,比如100w次,其实简单的就是控制单位时间的调用次数,防止业务洪流冲垮服务
- 统计活动,将一些调用信息统计好发送给Monitor端
Consumer消费者
简述:
它也是有两个网络角色,不过并不是精神分裂,它都是作为网络的客户端存在,一它需要去连接registry去获取到订阅信息,二是它需要主动去连接provider端去调用服务
职责:
- 去向Registry端订阅服务,拿到registry端返回的结果,这个结果也就是provider的网络地址,先建立TCP的长连接,可能是多个地址,因为提供某个服务的可能有多个提供者
- 当开始系统主动调用该服务的时候,拿到刚才建立的连接的集合,根据某个方法,是随意还是轮询,获取到其中的一个连接,发送方法入参,等待响应
- 当注册中心发送某个服务的调用的负载策略发生变化过,发送信息给consumer,consumer需要做相应的变更
Monitor监控者
简述:
这个与整个系统是没有任何直接的关系的,实现方式也是多样的,可以与上面一样建立长连接,接收每个角色统计的信息,然后展示给用户,可以使用MQ,使用消息队列,每个角色把自己统计的信息放到队列中,Monitor去消费这些信息,这样做的好处就是解耦,如果monitor宕了,不影响服务
大体的RPC的流程稍微理了一下,接下来我们就来一一去实现这些功能~