Python基础(①⑦gRPC)
Flask 适合:
做网站(返回 HTML 页面)
提供供浏览器 / 手机 APP 调用的 HTTP API(比如获取商品列表、用户登录)
场景:你开发一个电商 APP,需要从服务器获取商品数据,用 Flask 写个接口返回 JSON 就行。
gRPC 适合:
程序之间的高效通信(比如公司内部的多个服务之间调用)
需要频繁、快速传输数据的场景(比如游戏服务器和客户端、实时监控系统)
场景:你有两个服务器,A 服务器需要频繁调用 B 服务器的计算功能,用 gRPC 能比 HTTP 快很多。
安装必要的库
首先需要安装 gRPC 相关的 Python 库:
pip install grpcio grpcio-tools
定义服务接口(.proto 文件)
创建一个 calculator.proto
文件,定义服务和数据结构:
syntax = "proto3";// 定义包名,避免命名冲突
package calculator;// 定义服务
service CalculatorService {// 加法 RPCrpc Add(AddRequest) returns (AddResponse) {}// 乘法 RPCrpc Multiply(MultiplyRequest) returns (MultiplyResponse) {}
}// 加法请求消息
message AddRequest {int32 a = 1;int32 b = 2;
}// 加法响应消息
message AddResponse {int32 result = 1;
}// 乘法请求消息
message MultiplyRequest {int32 a = 1;int32 b = 2;
}// 乘法响应消息
message MultiplyResponse {int32 result = 1;
}
生成 Python 代码
使用 grpc_tools.protoc
工具根据 .proto
文件生成 Python 代码:
import os
import sys
from grpc_tools import protoc# 生成代码
protoc.main(['grpc_tools.protoc',f'--proto_path={os.path.dirname(__file__)}', # 指定proto文件目录f'--python_out={os.path.dirname(__file__)}', # 生成的Python代码目录f'--grpc_python_out={os.path.dirname(__file__)}', # 生成的gRPC Python代码目录os.path.join(os.path.dirname(__file__), 'calculator.proto') # proto文件路径
])print("代码生成完成")
运行这个脚本后,会生成两个文件:calculator_pb2.py
(数据结构相关)和 calculator_pb2_grpc.py
(服务相关)。
实现服务端
创建 server.py
文件,实现我们定义的服务:
import grpc
import time
from concurrent import futures
import calculator_pb2
import calculator_pb2_grpc# 实现服务接口
class CalculatorServicer(calculator_pb2_grpc.CalculatorServiceServicer):def Add(self, request, context):result = request.a + request.bprint(f"收到加法请求: {request.a} + {request.b} = {result}")return calculator_pb2.AddResponse(result=result)def Multiply(self, request, context):result = request.a * request.bprint(f"收到乘法请求: {request.a} * {request.b} = {result}")return calculator_pb2.MultiplyResponse(result=result)# 启动服务
def serve():# 创建服务器,使用5个线程处理请求server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))# 注册服务calculator_pb2_grpc.add_CalculatorServiceServicer_to_server(CalculatorServicer(), server)# 监听端口server.add_insecure_port('[::]:50051')server.start()print("服务器已启动,监听端口50051...")# 保持服务运行try:while True:time.sleep(60 * 60 * 24) # 一天except KeyboardInterrupt:server.stop(0)if __name__ == '__main__':serve()
实现客户端
创建 client.py
文件,用于调用服务:
import grpc
import calculator_pb2
import calculator_pb2_grpcdef run():# 连接服务器with grpc.insecure_channel('localhost:50051') as channel:# 创建客户端存根stub = calculator_pb2_grpc.CalculatorServiceStub(channel)# 调用加法服务add_response = stub.Add(calculator_pb2.AddRequest(a=10, b=20))print(f"加法结果: 10 + 20 = {add_response.result}")# 调用乘法服务multiply_response = stub.Multiply(calculator_pb2.MultiplyRequest(a=5, b=8))print(f"乘法结果: 5 * 8 = {multiply_response.result}")if __name__ == '__main__':run()
123