PRC
什么是RPC
远程过程调用(英语:Remote Procedure Call,缩写为 RPC,也叫远程程序调用)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用。
背景与用途
在单台计算机中,我们可以通过程序调用来传递控制和数据;或者说通过程序调用,我们可以将多个程序组成一个整体来实现某个功能。
如果将这种调用机制推广到多台彼此间可以进行网络通讯的计算机,由多台计算机中的多个程序组成一个整体来实现某个功能,这也是可以的。调用的一方(发起远程过程调用,然后调用这方的环境挂起,参数通过网络传递给被调用方,被调用的一方执行程序,当程序执行完成后,产生的结果再通过网络回传给调用的一方,调用的一方恢复继续执行。这样一种原型思想,就是我们所说的RPC远程过程调用。
RPC这种思想最早可以追溯到1976年,RPC的发展到今天已经40年有余了。
如今的计算机应用中,单机性能上很难承受住产品的压力,需要不断扩充多台机器来提升整体的性能。同时为了充分利用这些集群里的计算机,需要对其从架构上进行划分,以提供不同的服务,服务间相互调用完成整个产品的功能。RPC就能帮助我们解决这些服务间的信息传递和调用。
RPC结构
RPC的设计思想是力图使远程调用中的通讯细节对于使用者透明,调用双方无需关心网络通讯的具体实现。因而实现RPC要进行一定的封装。
RPC原理上是按如下结构流程进行实现的。
流程:
- 调用者(Caller, 也叫客户端、Client)以本地调用的方式发起调用;
- Client stub(客户端存根,可理解为辅助助手)收到调用后,负责将被调用的方法名、参数等打包编码成特定格式的能进行网络传输的消息体;
- Client stub将消息体通过网络发送给对端(服务端)
- Server stub(服务端存根,同样可理解为辅助助手)收到通过网络接收到消息后按照相应格式进行拆包解码,获取方法名和参数;
- Server stub根据方法名和参数进行本地调用;
- 被调用者(Callee,也叫Server)本地调用执行后将结果返回给server stub;
- Server stub将返回值打包编码成消息,并通过网络发送给对端(客户端);
- Client stub收到消息后,进行拆包解码,返回给Client;
- Client得到本次RPC调用的最终结果。
gRPC
gRPC是由Google公司开源的高性能RPC框架。
gRPC支持多语言
gRPC原生使用C、Java、Go进行了三种实现,而C语言实现的版本进行封装后又支持C++、C#、Node、ObjC、 Python、Ruby、PHP等开发语言
gRPC支持多平台
支持的平台包括:Linux、Android、iOS、MacOS、Windows
gRPC的消息协议使用Google自家开源的Protocol Buffers协议机制(proto3) 序列化
gRPC的传输使用HTTP/2标准,支持双向流和连接多路复用
Protocol Buffers
gRPC的消息协议使用Google自家开源的Protocol Buffers协议机制(proto3) 序列化
详情可看我的另一篇文章 Protocol Buffers
接口定义
接口原型
接口名称: proto_test
调用参数:
1 | ProtoTestReuqest: |
返回数据:
1 | ProtoTestResponse: |
使用Protobuf 定义的接口如下
使用protobuf定义的接口文件通常以proto作为文件后缀名
在rpc目录下新建protoTest.proto文件
1 | syntax = "proto3"; // 在gRPC中推荐使用proto3版本。 |
代码生成
安装protobuf编译器和grpc库
1 | pip install grpcio-tools |
编译生成代码
1 | python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. protoTest.proto |
-I
表示搜索proto文件中被导入文件的目录--python_out
表示保存生成Python文件的目录,生成的文件中包含接口定义中的数据类型--grpc_python_out
表示保存生成Python文件的目录,生成的文件中包含接口定义中的服务类型
在rpc目录下执行上述命令,会自动生成如下两个rpc调用辅助代码模块:
- protoTest_pb2.py 保存根据接口定义文件中的数据类型生成的python类
- protoTest_pb2_grpc.py 保存根据接口定义文件中的服务方法类型生成的python调用RPC方法
服务端
在rpc目录下新建server.py文件,用来补全服务端代码
1 | import protoTest_pb2 |
客户端
在rpc目录下新建client.py
1 | import grpc |