1、基础
prc、分布式计算、
Nelson :
------- 下文摘自 RPC 的概念模型与实现解析 ----------
模型
1. User
2. User-stub
3. RPCRuntime
4. Server-stub
5. Server
组件
-
RpcServer
负责导出(export)远程接口 -
RpcClient
负责导入(import)远程接口的代理实现 -
RpcProxy
远程接口的代理实现 -
RpcInvoker
客户端:负责编码调用信息和发送调用请求到服务端并等待调用结果返回
服务端:负责调用服务端接口的具体实现并返回调用结果 -
RpcProtocol
负责协议编/解码 -
RpcConnector
负责维持客户端和服务端的连接通道和发送数据到服务端 -
RpcAcceptor
负责接收客户端请求并返回请求结果 -
RpcProcessor
负责在服务端控制调用过程,包括管理调用线程池、超时时间等 -
RpcChannel
数据传输通道
协议
协议指 RPC 调用在网络传输中约定的数据封装方式,包括三个部分:编解码、消息头 和 消息体。
编解码
客户端代理在发起调用前需要对调用信息进行编码,这就要考虑需要编码些什么信息并以什么格式传输到服务端才能让服务端完成调用。 出于效率考虑,编码的信息越少越好(传输数据少),编码的规则越简单越好(执行效率高)。
我们先看下需要编码些什么信息:
调用编码
-
接口方法
包括接口名、方法名
-
方法参数
包括参数类型、参数值
-
调用属性
包括调用属性信息,例如调用附加的隐式参数、调用超时时间等
返回编码
-
返回结果
接口方法中定义的返回值
-
返回码
异常返回码
-
返回异常信息
调用异常信息
消息头
除了以上这些必须的调用信息,我们可能还需要一些元信息以方便程序编解码以及未来可能的扩展。这样我们的编码消息里面就分成了两部分,一部分是元信息、另一部分是调用的必要信息。如果设计一种 RPC 协议消息的话,元信息我们把它放在协议消息头中,而必要信息放在协议消息体中。下面给出一种概念上的 RPC 协议消息头设计格式:
-
magic
协议魔数,为解码设计
-
header size
协议头长度,为扩展设计
-
version
协议版本,为兼容设计
-
st
消息体序列化类型
-
hb
心跳消息标记,为长连接传输层心跳设计
-
ow
单向消息标记,
-
rp
响应消息标记,不置位默认是请求消息
-
status code
响应消息状态码
消息体
消息体常采用序列化编码,常见有以下序列化方式:
-
xml
如 webservie SOAP
-
json
如 JSON-RPC
-
binary
如 thrift; hession; kryo 等
格式确定后编解码就简单了,由于头长度一定所以我们比较关心的就是消息体的序列化方式。 序列化我们关心三个方面:
-
__效率__:序列化和反序列化的效率,越快越好。
-
__长度__:序列化后的字节长度,越小越好。
-
__兼容__:序列化和反序列化的兼容性,接口参数对象若增加了字段,是否兼容。
-
上面这三点有时是鱼与熊掌不可兼得,这里面涉及到具体的序列化库实现细节,就不在本文进一步展开分析了。
传输
协议编码之后,自然就是需要将编码后的 RPC 请求消息传输到服务端,服务方执行后返回结果消息或确认消息给客户端。RPC 的应用场景实质是一种可靠的请求应答消息流,这点和 HTTP 类似。因此选择长连接方式的 TCP 协议会更高效,与 HTTP 不同的是在协议层面我们定义了每个消息的唯一 id,因此可以更容易的复用连接。
既然使用长连接,那么第一个问题是到底客户端和服务端之间需要多少根连接?实际上单连接和多连接在使用上没有区别,对于数据传输量较小的应用类型,单连接基本足够。单连接和多连接最大的区别在于,每根连接都有自己私有的发送和接收缓冲区,因此大数据量传输时分散在不同的连接缓冲区会得到更好的吞吐效率。
所以,如果你的数据传输量不足以让单连接的缓冲区一直处于饱和状态的话,那么使用多连接并不会产生任何明显的提升,反而会增加连接管理的开销。
连接是由客户端发起建立并维持的,如果客户端和服务端之间是直连的,那么连接一般不会中断(当然物理链路故障除外)。如果客户端和服务端连接经过一些负载中转设备,有可能连接一段时间不活跃时会被这些中间设备中断。为了保持连接有必要定时为每个连接发送心跳数据以维持连接不中断。心跳消息是 RPC 框架库使用的内部消息,在前文协议头结构中也有一个专门的心跳位,就是用来标记心跳消息的,它对业务应用透明。
-
reserved
为字节对齐保留
-
message id
消息 id
-
body size
消息体长
RPC 的概念模型与实现解析 (这个仔细看)
主流RPC框架:(仅是概念)
Spring的HTTP Invoker(可以参考)
caucho提供的基于binary-RPC框架Hessian
Google开源的基于HTTP/2和ProtocolBuf的RPC框架gRPC(可以参考)
待续