RPC详解

博客链接指向一篇关于RPC详解的文章,虽未展示具体内容,但推测围绕RPC展开详细讲解,RPC在信息技术领域常用于远程过程调用,能实现不同进程间通信。

https://www.jianshu.com/p/2accc2840a1b

RPC(Remote Procedure Call,远程过程调用)是一种允许程序调用另一台机器上的函数或过程的协议。它使得开发者可以像调用本地函数一样调用远程服务,屏蔽了底层网络通信的复杂性。 在 Python 中,实现 RPC 的方式有多种,包括基于自定义 socket 通信、gRPC、Thrift、ZeroRPC、XML-RPC、JSON-RPC 等。 --- ### 1. RPC 基本原理 RPC 的核心思想是:**客户端像调用本地函数一样调用远程服务器上的函数,而底层的网络通信、序列化、反序列化等由框架自动完成。** #### 典型流程: 1. 客户端调用一个本地的“代理”函数(stub)。 2. 该代理将函数名、参数等信息**序列化**(如 JSON、Protobuf)。 3. 通过网络发送到服务器(通常使用 TCP/HTTP)。 4. 服务器接收到请求后,**反序列化**数据。 5. 查找并调用对应的实际函数。 6. 将结果序列化后返回给客户端。 7. 客户端反序列化结果并返回给调用者。 --- ### 2. 使用 `xmlrpc` 实现简单的 RPC(Python 内置) Python 标准库提供了 `xmlrpc` 模块,基于 HTTP 和 XML 实现简单 RPC。 #### 服务端代码: ```python from xmlrpc.server import SimpleXMLRPCServer def add(x, y): return x + y def multiply(x, y): return x * y # 创建服务器 server = SimpleXMLRPCServer(("localhost", 8000)) print("Listening on port 8000...") # 注册函数 server.register_function(add, 'add') server.register_function(multiply, 'multiply') # 启动服务 server.serve_forever() ``` #### 客户端代码: ```python import xmlrpc.client # 连接到服务器 proxy = xmlrpc.client.ServerProxy('http://localhost:8000/') # 调用远程函数 print(proxy.add(5, 3)) # 输出: 8 print(proxy.multiply(5, 3)) # 输出: 15 ``` > ✅ 优点:标准库支持,无需安装第三方包,适合学习和小型项目。 > ❌ 缺点:性能较低,XML 序列化体积大,不支持复杂类型。 --- ### 3. 使用 gRPC(高性能生产级 RPC 框架) gRPC 是 Google 开发的高性能 RPC 框架,使用 Protocol Buffers 作为接口定义语言(IDL),支持多语言,基于 HTTP/2。 #### 步骤: 1. 定义 `.proto` 文件 2. 生成 Python 代码 3. 实现服务端和客户端 ##### 示例 `.proto` 文件(`example.proto`): ```protobuf syntax = "proto3"; service Calculator { rpc Add (AddRequest) returns (AddResponse); } message AddRequest { int32 a = 1; int32 b = 2; } message AddResponse { int32 result = 1; } ``` ##### 生成 Python 代码: ```bash python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. example.proto ``` 这会生成 `example_pb2.py` 和 `example_pb2_grpc.py`。 ##### 服务端代码: ```python import grpc from concurrent import futures import example_pb2 import example_pb2_grpc class CalculatorServicer(example_pb2_grpc.CalculatorServicer): def Add(self, request, context): result = request.a + request.b return example_pb2.AddResponse(result=result) def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) example_pb2_grpc.add_CalculatorServicer_to_server(CalculatorServicer(), server) server.add_insecure_port('[::]:50051') print("gRPC server running on port 50051...") server.start() server.wait_for_termination() if __name__ == '__main__': serve() ``` ##### 客户端代码: ```python import grpc import example_pb2 import example_pb2_grpc def run(): with grpc.insecure_channel('localhost:50051') as channel: stub = example_pb2_grpc.CalculatorStub(channel) response = stub.Add(example_pb2.AddRequest(a=3, b=5)) print("Result:", response.result) if __name__ == '__main__': run() ``` > ✅ 优点:高性能、强类型、支持流式通信、跨语言。 > ❌ 缺点:需要学习 Protocol Buffers,配置较复杂。 --- ### 4. 使用 ZeroRPC(基于 ZeroMQ) ZeroRPC 是一个轻量级的 RPC 库,使用 MessagePack 序列化,性能较好。 安装: ```bash pip install zerorpc ``` ##### 服务端: ```python import zerorpc class Calculator: def add(self, a, b): return a + b server = zerorpc.Server(Calculator()) server.bind("tcp://0.0.0.0:4242") print("ZeroRPC server running on port 4242...") server.run() ``` ##### 客户端: ```python import zerorpc client = zerorpc.Client() client.connect("tcp://127.0.0.1:4242") print(client.add(5, 3)) # 输出: 8 client.close() ``` > ✅ 优点:简洁易用,性能好。 > ❌ 缺点:社区较小,文档较少。 --- ### 5. 自定义简易 RPC(基于 socket + pickle) 演示原理,不推荐用于生产。 ##### 服务端: ```python import socket import pickle import threading def handle_client(conn, addr): try: data = conn.recv(1024) func_name, args, kwargs = pickle.loads(data) # 模拟函数注册表 functions = {'add': lambda x, y: x + y} if func_name in functions: result = functions[func_name](*args, **kwargs) conn.send(pickle.dumps(result)) except Exception as e: conn.send(pickle.dumps(e)) finally: conn.close() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 9999)) sock.listen(5) print("Custom RPC server listening on port 9999...") while True: conn, addr = sock.accept() thread = threading.Thread(target=handle_client, args=(conn, addr)) thread.start() ``` ##### 客户端: ```python import socket import pickle def rpc_call(host, port, func_name, *args, **kwargs): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((host, port)) client.send(pickle.dumps((func_name, args, kwargs))) result_data = client.recv(1024) result = pickle.loads(result_data) client.close() if isinstance(result, Exception): raise result return result # 调用远程函数 print(rpc_call('localhost', 9999, 'add', 5, 3)) # 输出: 8 ``` > ⚠️ 注意:`pickle` 不安全,仅限内网使用;无错误重试、超时等机制。 --- ### 总结对比 | 方案 | 协议 | 序列化 | 性能 | 易用性 | 适用场景 | |------------|-----------|------------|------|--------|------------------------| | XML-RPC | HTTP/XML | XML | 低 | 高 | 学习、简单脚本 | | JSON-RPC | HTTP/JSON | JSON | 中 | 高 | Web 交互 | | gRPC | HTTP/2 | Protobuf | 高 | 中 | 微服务、高性能系统 | | ZeroRPC | TCP | MessagePack| 高 | 高 | 快速原型、内部服务 | | 自定义 RPC | TCP/UDP | Pickle等 | 可控 | 低 | 教学、理解原理 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值