目录


mac-rpc 全异步高性能RPC框架

基本概念

  mac-rpc是基于Java AIO开发的全异步、高性能RPC(远程方法调用)框架,它没有使用Netty等第三方网络通讯组件,则是从底层的网络通讯写起,采用了类似事件驱动的远程调用机制,能够减少了阻塞和线程切换开销,提高CPU的使用效率。这使得mac-rpc有着优异的性能表现和与众不同的能力,尤其是在对异步方法调用的支持上。
  优秀的设计使得mac-rpc十会的简洁优雅,在实现强大功能的同时,保持了小巧灵活的特点、极具扩展性,允许定制传输协议、序列化方式等。
  注:mac-rpc标配使用hessian作为序列化组件(可替换,包括去除依赖)
  在使用上,除了必须依赖 spring外(core,beans,context,aop)实现了对应用的“零侵入”。

服务四要素

  以下四个要素用以确定一个服务:

服务消费者与提供者

  在基于远程方法调用(RPC)的微服务架构设计理念中,一个可供远程调用的方法即被视为一个服务,远程方法调用的发起方(调用方)就是这一服务的消费者(Consumer),被调用方(服务方)就是这一服务的提供者(Provider)。
  通常一个应用可能会暴露多个可供远程调用的方法,也可能会需要调用多个远程方法。这要求本地应用持有这些远程方法的本地引用。MAC-RPC采用JAVA的动态代理机制,为每一个需要引用的远程方法在本地动态创建对应的“引用”——动态代理对象(Proxy)。
  应用是服务的“容器”,应用的实例被称为节点(Node)。

服务注册与发现

  在基于MAC-RPC的微服务环境中,一个应用的一个实例就是一个节点。节点之间通过一个叫做“注册中心”地方交换服务信息,实现服务层面的服务注册与发现。
  MAC-RPC采用所谓的“弱中心化”设计,任何一个节点均可以被标记为主节点(master),而主节点在MAC-RPC中就扮演了服务的注册中心的角色,并且可以有多个。   普通的RPC节点连接到其中任意一个master节点就可以与其它所有节点连通。
  所节点都通过主节点进行注册表交换,过程如下:
  1. 所有节点将自身的注册信息(注册表)提交到它的主节点(可能是N3,也可能是N4)。
  2. 由该主节点将此注册表保存在内存中,并推送到所有与之连接的节点。注:一个普通节点只会连接一个主节点。
  3. 各节点在收到推送后,判断是否比已持有的对应注册表更新,是则更新本地内存中的注册表。
  4. 主节点在收到来自其它主节点的推送,且当收到的注册表比自己持有的更新时,会推送此注册表到与之连接的所有节点。

远程方法调用过程

  在双方完成服务的注册与发现后,就可以通过远程调用彼此提供的方法。其间不再需要通过主节点。即使主节点宕机,也不受影响。
  下图展示了节点N2调用N1提供的服务X的过程:

overview
  1. Bean B获取Bean R的引用,并转换为X接口,调用其中的方法Y
  2. Bean R是RPC框架预先就动态创建好的类R的实例(对应consume.xml中的reference),它先根据配置的负载均衡算法挑出一个服务X提供者(N1)。再将本次方法调用封装为数据对象,交给RPC网络通讯层
  3. RPC通讯层将数据对象序列化、拆包,通过网络发送给N1
  4. N1的RPC通讯层负责接收这些数据包组包、还原,再反序列化后得到数据对象,确定要调用Bean S的对应方法。
  5. Bean S是为了不侵入目标Bean A,由RPC框架预先创建好了Bean A的代理类,框架通过它调用Bean A中的对应方法
  6. Bean A中的方法执行完毕后,将结果返回给Bean S(或抛出异常给Bean S捕获)
  7. 调用完成后,由Bean S将返回的结果封装为数据对象,交给RPC网络通讯层
  8. N1的RPC网络通讯层将数据对象序列化、拆包,通过网络发送给N2
  9. N2的RPC网络通讯层将这些数据包组包、还原,再反序列化后得到数据对象,交给Bean R
  10. Bean R从数据对象中提出返回信息,包括调用结果和异常信息,作为方法调用的结果返回

方法调用类型

  mac-rpc支持以下方法调用类型:
  1. 同步方法(SC):调用方在调起远程方法后阻塞,等待远程方法的返回
  2. 异步方法(AC):异步调用方法的返回类型必须声明为Object,在编写实现时,需要返回真实的结果。但调用方在调用时获得的是一个Future<Object>
  3. 同步通知(SN):调用远程方法,对方会开始异步执行,并立即返回一个签收应答。
  4. 异步通知(AN):异步通知方法的返回类型必须声明为Object。服务方在收到请求后,会开始异步执行,并立即返回一个签收应答。而调用方调用远程方法,不会阻塞当前线,拿到的返回值是Future<Object>类型,调用其get方法时才会阻塞,以等待实际的返回值——来自服务方的签收应答。
  5. 同步广播方法(SB):也是是需要特殊处理的方法,其返回值必须是Object类型。在编写服务方的实现时,需要返回真实的结果。但在服务的调用方(服务消费者)拿到的对象却时Map<String, Object>类型。此map的key是执行此方法的节点的地址,形如:IP:PORT,而map的value才是实际的结果。
  6. 异步广播方法(AB):异步广播方法与同步广播方法在处理上基本相同。异步广播方法采用Future模式,返回Map<String, Future<Object>>,因此在获取实际结果前不会阻塞当前线程。
  7. 广播通知方法(BN):广播通知与异步广播方法在处理上相近。不同之处在于,服务端在收到请求后,不是同步执行,返回执行结果,而是异步执行,并立即返回签收应答。调用方拿到的返回值也是Map<String, Future<Object>>类型,只是从Future中get的只是签收应答,而不是远程方法的实际执行结果。