什么是 RPC?
RPC全称remote procedure call ,即远程过程调用,RPC 看起来好像客户端直接调用位于远程服务器程序中的过程。
在 RPC 期间将执行以下步骤:
- 客户端调用客户端存根(stub) 过程,以常规方式传递参数。客户端存根驻留在客户端自己的地址空间中。
- 客户端存根将参数打包到消息中。打包包括将参数的表示形式转换为标准格式,并将每个参数复制到消息中。
- 客户端存根将消息传递到传输层,传输层将其发送到远程服务器计算机。
- 在服务器上,传输层将消息传递到服务器存根,该存根解压缩参数并使用常规过程调用机制调用所需的服务器例程。
- 当服务器过程完成时,它会返回到服务器存根(例如,通过正常过程调用返回),该存根将返回值封装到消息中。然后,服务器存根将消息传递给传输层。
- 传输层将结果消息发送回客户端传输层,客户端传输层将消息传递回客户端存根。
- 客户端存根解绑返回参数,执行返回给调用方。
进程间通信使用RPC的优点
- RPC 使得进程之间通信非常便捷,省略了许多协议层以提高性能,不需要编写socket,也不需要为了Web API 搭建一套WEB部署环境,只需要实现RPC接口。
- RPC 允许在分布式环境中使用应用程序,而不仅仅是在本地环境中,即1个服务器,允许多个客户机调用。
- 使用 RPC, 使用开发工作量被最小化。
Python 简单RPC 实现
Xmlrpc.server, xmlrpc.client 是python内置模块,实现RPC非常容易。
服务端代码
from xmlrpc.server import SimpleXMLRPCServer
# Create server
with SimpleXMLRPCServer(('localhost', 8000),) as server:
server.register_introspection_functions()
# Register pow() function,pow()是内置方法
server.register_function(pow)
# Register a function under a different name
def adder_function(x, y):
return x + y
server.register_function(adder_function, 'add')
# Register an instance; all the methods of the instance are
# published as XML-RPC methods (in this case, just 'mul').
class MyFuncs:
def mul(self, x, y):
return x * y
server.register_instance(MyFuncs())
# Run the server's main loop
server.serve_forever()
客户端调用服务器方法的代码
import xmlrpc.client
s = xmlrpc.client.ServerProxy('http://localhost:8000')
print(s.pow(2,3)) # Returns 2**3 = 8
print(s.add(2,3)) # Returns 5
print(s.mul(5,2)) # Returns 5*2 = 10
# Print list of available methods
print(s.system.listMethods())
服务器使用方法注册装饰器
服务器端,register_function() 也可被用作装饰器。 上述服务器端示例可以通过装饰器方式来注册函数:
@server.register_function(name='add')
def adder_function(x, y):
return x + y
# Register a function under function.__name__.
@server.register_function
def mul(x, y):
return x * y
效果是相同的。
XMLRPC 开发过程的一些建议
- 服务器方法的参数类型建议都使用 python 标准类型如string, list, tuple, dict 等,以避免参数类型理解不一致造成对接效率低。
- 简单 RPC方式本身安全性较差,因此最好只用于内网,不要用于外网
- 如果接口参数都是自定义类型,且数据尺寸大,建立使用gRPC,效率更高。