由于之前项目中用到了java的rmi,这里来分析一下主流的rpc框架:rmi,thrift,dubbo和protobuff。

Overview

RPC 全称 Remote Procedure Call——远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的方式。简单一点就是:通过一定协议和方法使得调用远程计算机上的服务,就像调用本地服务一样。

通常来说,RPC 的实现方式有很多,可以基于常见的 HTTP 协议,也可以在TCP上层封装自定义协议,常见的 Web Service 就是基于 HTTP 协议的 RPC,HTTP 协议的优点是具有良好的跨平台性,特别适合异构系统较多的公司,但是由于 HTTP 报头较为冗长,性能较差,基于 TCP 协议的 RPC 可以建立长连接,速度和效率明显,但是难度和复杂程度很高。

RPC可以按照协议来划分为http、tcp、二进制,也可以跨语言来进行调用(gRPC)。

RPC框架剖析

一个完整的RPC框架主要包含一下模块:
image.png
服务端主要包含一下功能:

  1. 负责将RPC状态导出,即导出执行结果
  2. 执行注册在其上的函数方法,调用invoke执行对应的方法
  3. 负责维持长链接通道与传输协议

而客户端主要包含:

  1. 指定调用的远程方法名称与调用参数
  2. 使用动态代理的方式织入远程的方法实现
  3. 负责维持长链接通道与传输协议

下面是一个简单的例子:

Server:
image.png

Client:
image.png

主流RPC框架对比

RMI

rmi是最早期的java rpc调用框架,其基本原理如下:
image.png
首先服务器新建一个register(这里有可能在server本地)到某一特定端口,之后即可以在register通过命名来绑定服务。而服务器则从指定端口获取register后,通过名称找到对应的服务接口,再传入希望调用的方法名和参数,即可得到返回结果对象。

Hessian

Hessian是基于http的远程调用方法,其淡化了register的概念,客户端通过显示的地址调用生成代理对象。
image.png

Dubbo

Dubbo是基于netty高性能RPC框架,其基于TCP进行传输。
image.png
可以看到其在RMI基础上使用了ZK来代替register的位置,而且底层传输使用了netty来提升网络传输性能。

gRPC

gRPC是google开发的语言中立,平台中立的RPC系统,其基于HTTP/2,使用protobuf来作为通信单元。其缺点是未提供线程池机制与“服务发现,负载均衡”等机制,并且protobuf是二进制的,其可读性较差。