Python 实现 gRPC 与 原始 RPC 的对比:理解 RPC 的基本功能
在分布式系统中,远程过程调用(Remote Procedure Call,RPC) 是一项关键技术,它允许不同计算机之间像调用本地函数一样进行通信。本文通过 Python 代码对比 gRPC 和 原始 RPC(基于 Socket) 来分析 RPC 的基本功能。
1. 什么是 RPC?
RPC(Remote Procedure Call) 是一种允许程序在 不同的进程、机器 之间像调用本地函数一样执行远程函数的技术。本地进程(客户端)调用远程服务器上的方法,服务器执行方法后将结果返回给客户端。
RPC 的核心功能
- 客户端-服务器通信:通过网络请求调用远程方法
- 序列化与反序列化:将数据转换成可传输格式(JSON、Protobuf)
- 自动化传输:隐藏底层通信逻辑,让调用方式更直观
- 错误处理:支持异常返回
2. gRPC 与 原始 RPC(基于 Socket) 对比
功能 | gRPC | 原始 RPC(Socket) |
---|---|---|
序列化 | Protobuf(二进制,高效) | JSON(文本格式,易读但体积大) |
传输协议 | HTTP/2(高性能) | 纯 TCP(需手写协议) |
代码生成 | 支持 .proto 自动生成 | 需手写所有请求/响应逻辑 |
流式通信 | 支持(客户端流、服务器流、双向流) | 需要手动实现 |
多语言支持 | Python、Go、Java 等 | 仅限 Python(除非自行实现跨语言支持) |
安全性 | 内置 TLS/SSL 支持 | 需手动加密 |
性能 | 高效、低延迟 | 较低(TCP+JSON 开销大) |
接下来,我们分别实现 gRPC 和 原始 RPC 进行对比。
3. gRPC 实现
gRPC 使用 Protobuf 进行序列化,并自动生成 客户端和服务器端代码。
3.1 定义 gRPC 服务
创建 rpc_service.proto
:
syntax = "proto3";
package rpcdemo;
service MathService {
rpc Add (AddRequest) returns (AddResponse);
}
message AddRequest {
int32 a = 1;
int32 b = 2;
}
message AddResponse {
int32 result = 1;
}
生成 Python 代码:
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. rpc_service.proto
3.2 gRPC 服务器
import grpc
from concurrent import futures
import rpc_service_pb2
import rpc_service_pb2_grpc
class MathService(rpc_service_pb2_grpc.MathServiceServicer):
def Add(self, request, context):
return rpc_service_pb2.AddResponse(result=request.a + request.b)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
rpc_service_pb2_grpc.add_MathServiceServicer_to_server(MathService(), server)
server.add_insecure_port('[::]:50051')
server.start()
print("gRPC Server started on port 50051")
server.wait_for_termination()
if __name__ == "__main__":
serve()
3.3 gRPC 客户端
import grpc
import rpc_service_pb2
import rpc_service_pb2_grpc
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = rpc_service_pb2_grpc.MathServiceStub(channel)
response = stub.Add(rpc_service_pb2.AddRequest(a=10, b=20))
print("gRPC Response:", response.result)
if __name__ == "__main__":
run()
4. 原始 RPC(Socket 实现)
使用 Python 原生 socket 来模拟 RPC 机制。
4.1 原始 RPC 服务器
import socket
import json
# 定义计算服务
def add(a, b):
return a + b
# 注册可调用的函数
FUNCTIONS = {
"add": add
}
def handle_client_connection(client_socket):
""" 处理客户端请求 """
try:
# 接收数据
data = client_socket.recv(1024).decode('utf-8')
request = json.loads(data)
# 获取方法名和参数
method = request.get("method")
params = request.get("params", [])
# 执行方法
if method in FUNCTIONS:
result = FUNCTIONS[method](*params)
response = {"status": "success", "result": result}
else:
response = {"status": "error", "message": "Method not found"}
# 发送响应
client_socket.send(json.dumps(response).encode('utf-8'))
except Exception as e:
response = {"status": "error", "message": str(e)}
client_socket.send(json.dumps(response).encode('utf-8'))
finally:
client_socket.close()
def start_server(host='localhost', port=5000):
""" 启动RPC服务器 """
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(5)
print(f"RPC Server listening on {host}:{port}")
while True:
client_sock, _ = server.accept()
handle_client_connection(client_sock)
if __name__ == "__main__":
start_server()
4.2 原始 RPC 客户端
import socket
import json
def rpc_call(method, params, host='localhost', port=5000):
""" 发送 RPC 请求 """
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
# 构造请求数据
request = json.dumps({
"method": method,
"params": params
})
# 发送数据
client.send(request.encode('utf-8'))
# 接收响应
response_data = client.recv(1024).decode('utf-8')
response = json.loads(response_data)
client.close()
return response
if __name__ == "__main__":
result = rpc_call("add", [10, 20])
print("RPC Response:", result)
5. 总结
5.1 gRPC 与 原始 RPC 的区别
特性 | gRPC | 原始 RPC(Socket) |
---|---|---|
序列化方式 | Protobuf(高效二进制) | JSON(文本格式) |
传输协议 | HTTP/2 | TCP |
自动代码生成 | 支持(通过 .proto ) | 不支持(需手动实现) |
流式传输 | 支持(双向流、流式响应) | 需要手动实现 |
多语言支持 | 支持多种语言(Python、Go、Java 等) | 仅支持 Python |
性能 | 高效,低延迟 | 相对较慢(TCP+JSON 有额外开销) |
5.2 选择哪种 RPC?
✅ gRPC 适用于:
- 分布式系统(微服务架构)
- 多语言通信(前端、后端不同语言)
- 高性能数据传输(Protobuf + HTTP/2)
✅ 原始 RPC(Socket) 适用于:
- 小型应用(轻量级进程间通信)
- 学习 RPC 原理
- 内部服务(单机内进程间通信)
若有错误与不足请指出,关注DPT一起进步吧!!!