用Python编写简单的gRPC服务的详细过程

1. 什么是gRPC

grpc 是由谷歌推出的一个高性能、开源、通用的rpc框架, 它基于http/2标准协议, 采用protobuf(Protocol Buffers)作为数据传输格式, 提供了多种语言的支持。

grpc的两个核心组件:

protobuf: 谷歌的高性能、可扩展、结构化数据存储格式,支持多种语言

http/2: 具有流控制、多路复用等功能的tcp基础协议

与RESTful API比较, grpc 的优势:

它支持流数据,可在多个消息之间建立一条TCP连接, 每个消息只是流中的一个包

每个包就是一个RPC,因此它允许服务器同时向客户端推送多个消息/对象

gRPC 的协议使用的是二进制,不像 JSON 和 XML 那样文本格式在更新和升级时产生大量的额外字节

使用ProtoBufs 进行序列化(而不是JSON),因此它不仅更小,而且速度更快

2. gRPC服务的搭建

2.1 安装grpc

利用pip命令安装grpc:

pip install grpcio

安装完grpcio后安装grpcio-tools:

pip install grpcio-tools

2.2 定义proto文件

在proto文件中定义服务和数据类型:

syntax = "proto3";

// 定义 Hello Service

service Greeter {

// 定义 SayHello 方法

rpc SayHello (HelloRequest) returns (HelloReply) {}

}

message HelloRequest {

string name = 1;

}

message HelloReply {

string message = 1;

}

2.3 生成代码

执行命令生成python文件:

python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. hello.proto

将会在当前目录下生成hello_pb2.py和hello_pb2_grpc.py两个文件, pb2.py文件中包含生成的消息的定义, pb2_grpc.py文件中包含生成的 RPC 服务接口和方法。

2.4 实现服务

在hello_pb2_grpc.py文件中找到GreeterServicer类, 并在其中实现服务:

class GreeterServicer(hello_pb2_grpc.GreeterServicer):

def SayHello(self, request, context):

return hello_pb2.HelloReply(message=f"Hello, {request.name}!")

其中SayHello方法即为在proto文件中定义的方法

2.5 创建服务器

在服务器文件中创建服务器, 并设置绑定端口, 配置线程池:

def serve():

server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

hello_pb2_grpc.add_GreeterServicer_to_server(GreeterServicer(), server)

server.add_insecure_port('[::]:50051')

server.start()

server.wait_for_termination()

10个线程的线程池是使用futures库创建的ThreadPoolExecutor对象, 在add_GreeterServicer_to_server()方法中将GreeterServicer类对象和服务器对象进行绑定, 在add_insecure_port()方法中设置绑定端口, 在start()函数中启动服务器

3. 客户端的访问

通过在客户端实例化一个实现方法的stub, 可以通过网络请求到服务端数据。看下面的示例:

def run():

channel = grpc.insecure_channel('localhost:50051')

stub = hello_pb2_grpc.GreeterStub(channel)

response = stub.SayHello(hello_pb2.HelloRequest(name="grpc"))

print("Greeter client received: " + response.message)

在创建的客户端通道中指定服务器的地址和绑定的端口。然后实例化GreeterStub类以及其中的SayHello方法,并通过实例传递HelloRequest对象请求到服务端,并打印服务端返回的HelloReply对象中的message

4. 运行gRPC服务

运行服务器文件即可启动gRPC服务:

if __name__ == '__main__':

serve()

然后在客户端文件中运行客户端即可执行RPC调用:

if __name__ == '__main__':

run()

至此,一个最简单的gRPC服务就搭建完成了!

后端开发标签