远程过程调用(英语:Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。
为什么需要 RPC
基于 socket 接口我们也可以编写分布式应用,但是该方法存在着一些缺点。许多的细节需要程序员去处理,比如如何在同一个连接中分离不同的请求?不同机器上不同的方式实现的进程如何从网络读写数据?
正如计算机中其他问题的解决思路一样,我们可以在 socket 上提供另一层,隐藏一些和实际任务关系不大的细节,这一层也就是 RPC。RPC 提供易于网络编程的通信,使客户端服务端通信透明化,程序员无需关注网络通信的细节。最终达到让远程过程调用表现为本地调用的目标。
RPC 的生命周期
RPC 的实现需要以下步骤:
创建存根程序 (stub functions),让用户感觉是在执行本地调用
客户端存根程序 (proxy) 拥有调用接口,打包参数并调用服务器端程序
服务器存根程序 (skeleton) 接受请求并调用本地程序
服务器存根程序由两部分组成,Dispatcher 接受客户请求,并分发给特定程序调用。Skeletion 将网络消息解析为本地类型,调用本地程序,封装返回结果并返回给 Dispatcher。
一个 RPC 请求调用流程如下:
1. 客户端调用存根程序(将参数压入栈中)
2. 存根程序将参数转化为网络消息 (marshal)
3. 客户端操作系统给服务器发送一个网络消息
4. 服务器操作系统接收到消息,并将其向上发送给存根程序
5. 服务器存根程序解析参数,并调用服务器相应程序(unmarlshal)
6. 服务器程序运行,并返回值
7. 服务器存根将返回值转化为网络消息,并发送给服务器操作系统(marshal)
8. 服务器操作系统将返回值通过网络返回给客户端
9. 客户端操作系统接收到返回值,并传递给存根程序
10. 客户端存根解析返回值,并返回给客户端调用程序
好了,基于以上的理论知识,下面我们 用swoole来搭建一个rpc服务调用。
首先安装swoole扩展
最新的swoole扩展;
接着安装最新的swoft框架。分别下载2个:
一个 作为http,另外一个作为rpc服务,分别配置 如下:
分别启动 http 和rpc服务:
php bin/swoft server:start
php bin/swoft rpc:start
接着我们写个http服务来调用rpc的控制器:
在另外一个rpc服务里面,我们写rpc接收数据和处理的控制器:
这个时候在页面调用:
可以看到rpc已经返回我们调用的方法和 数据。我们打印http调用输出参数:
rpc服务收到请求响应:
以上是简单的rpc应用实例,它能大大降低架构微服务化的成本,提高调用方与服务提供方的研发效率,屏蔽跨进程调用函数(服务)的各类复杂细节,让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务,在分布式应用方面有着广泛的应用。