RPC

RPC(Remote Procedure Call)远程过程调用,是一种计算机通信协议。维基中这么定义-该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。

通过使用RPC,程序员在分布式应用中可以避免底层网络接口通信的细节,让你在调用远程程序时候就像调用本地程序一样。

HTTP与RPC之间的关系:

在一开始我对于HTTP和RPC也是有点混乱,后来理清楚之后认为HTTP是属于OSI模型中的应用层协议,而RPC是一种通信协议,这两者就像在问我火影忍者的鸣人和七龙珠的孙悟空那个厉害一样。当然,从应用层面而言,我们在分布式系统中通信,例如跨企业服务调用的时候,用的是HTTP API,所以HTTP和RPC在应用层面而言是相似的,没有很大的区别,谷歌的gRPC框架就是建立在HTTP2.0协议上。

RPC交互过程

RPC 是两个子系统之间进行的直接消息交互,它使用操作系统提供的套接字来作为消息的载体,以特定的消息格式来定义消息内容和边界。RPC 的客户端通过文件描述符的读写 API (read & write) 来访问操作系统内核中的网络模块为当前套接字分配的发送 (send buffer) 和接收 (recv buffer) 缓存。
如上图所示,左边的客户端进程写 RPC 指令消息到内核的发送缓存中,内核将发送缓存中的数据传送到物理硬件 NIC,也就是网络接口芯片 (Network Interface Circuit)。NIC 负责将翻译出来的模拟信号通过网络硬件传递到服务器硬件的 NIC。服务器的 NIC 再将模拟信号转成字节数据存放到内核为套接字分配的接收缓存中,最终服务器进程从接收缓存中读取数据即为源客户端进程传递过来的 RPC 指令消息。消息从用户进程流向物理硬件,又从物理硬件流向用户进程,中间还经过了一系列的路由网关节点。

RPC设计


如上图,首先必须得建立网络连接模块,负责建立,管理和消息的传输,其次要有编解码,对数据进行序列化与反序列化,这样才能在网络中传输,而对于一串消息流,必须能确定消息边界,提取单条消息的字节流片段,然后根据这个片段进行反序列化生成相应消息对象
RPC需要在一条TCP链接上进行多次消息传递,单条消息如果过大,就会被网络协议栈拆分为多个数据包进行传送。如果消息过小,网络协议栈可能会将多个消息组合成一个数据包进行发送。对于接收端来说它看到的只是一串串的字节数组,如果没有明确的消息边界规则,接收端是无从知道这一串字节数组究竟是包含多条消息还是只是某条消息的一部分。

消息边界

基于以上原因,常见的分割方式是特殊分隔符法和长度前缀法

特俗分隔符法是消息发送端在每条信息末尾追加一个特殊分割符,并且保证消息体不包含这个分隔符,比较常见的是\r\n。常用于文本消息。

长度前缀法是在每条消息的开头增加一个4字节长度整数值标志消息体长度,消息接收者首先读取长度信息,然后读取相应长度字节数据就能将一个完整信息分离出,适用于二进制消息

常见例子如HTTP协议,HTTP 协议是一种基于特殊分割符和长度前缀法的混合型协议。比如 HTTP 的消息头采用的是纯文本外加\r\n 分割符,而消息体则是通过消息头中的 Content-Type 的值来决定长度。HTTP 协议虽然被称之为文本传输协议,但是也可以在消息体中传输二进制数据数据的,例如音视频图像。

消息结构

每条消息都有它包含的语义结构信息,有些消息协议的结构信息是显式的,还有些是隐式的。比如 json 消息,它的结构就可以直接通过它的内容体现出来,所以它是一种显式结构的消息协议。json的可读性很好,但是缺点也是有太多的冗余信息,比如每个字符串都用双引号括起来,连续的多条 json 消息即使结构完全一样,仅仅只是 value 的值不一样,也需要发送同样的 key 字符串信息。

而有些结构则是由代码来约定消息协议,我们可以称之为隐式消息结构
一个简单的PHP实现例子,更详细见链接:

class xmlrpc_client {
    private $url;
    function __construct($url, $autoload=true) {
        $this->url = $url;
        $this->connection = new curl;
        $this->methods = array();
        if ($autoload) {
            $resp = $this->call('system.listMethods', null);
            $this->methods = $resp;
        }
    }
    public function call($method, $params = null) {
        $post = xmlrpc_encode_request($method, $params);
        return xmlrpc_decode($this->connection->post($this->url, $post));
    }
}
header('Content-Type: text/plain');
$rpc = "http://10.0.0.10/api.php";
$client = new xmlrpc_client($rpc, true);
$resp = $client->call('methodname', array());
print_r($resp);

相关链接:
JSON-RPC 2.0 规范(中文版)
jsonrpc
yar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值