gRPC 是 Google 开放的一款 RPC (Remote Procedure Call) 框架,建立在 HTTP2 之上,使用 Protocol Buffers。
Protocol Buffers 简介
protocol buffers 是 Google 公司开发的一种数据描述语言,采用简单的二进制格式,比 XML、JSON 格式体积更小,编解码效率更高。用于数据存储、通信协议等方面。
通过一个 .proto
文件,你可以定义你的数据的结构,并生成基于各种语言的代码。目前支持的语言很多,有 Python、golang、js、java 等等。
gRPC 简介
有了 protocol buffers 之后,Google 进一步推出了 gRPC。通过 gRPC,我们可以在 .proto
文件中也一并定义好 service,让远端使用的 client 可以如同调用本地的 library 一样使用。
可以看到 gRPC Server 是由 C++ 写的,Client 则分別是 Java 以及 Ruby,Server 跟 Client 端则是通过 protocol buffers 来信息传递。
1. 定义功能函数
calculate.py
# -*- coding: utf-8 -*-
import math
# 求平方
def square(x):
return math.sqrt(x)
2. 创建 .proto 文件
在这里描述我们要使用的 message 以及 service
calculate.proto
syntax = "proto3";
message Number {
float value = 1;
}
service Calculate {
rpc Square(Number) returns (Number) {}
}
3. 生成 gRPC 类
这部分可能是整个过程中最“黑盒子”的部分。我们将使用特殊工具自动生成类。
$ pip install grpcio grpcio-tools
$ python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. calculate.proto
你会看到生成来两个文件:
- calculate_pb2.py — 包含 message(calculate_pb2.Number)
- calculate_pb2_grpc.py — 包含 server(calculate_pb2_grpc.CalculatorServicer) and client(calculate_pb2_grpc.CalculatorStub)
4. 创建 gRPC 服务端
server.py
# -*- coding: utf-8 -*-
import grpc
import calculate_pb2
import calculate_pb2_grpc
import calculate
from concurrent import futures
import time
# 创建一个 CalculateServicer 继承自 calculate_pb2_grpc.CalculateServicer
class CalculateServicer(calculate_pb2_grpc.CalculateServicer):
def Square(self, request, context):
response = calculate_pb2.Number()
response.value = calculate.square(request.value)
return response
# 创建一个 gRPC server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 利用 add_CalculateServicer_to_server 这个方法把上面定义的 CalculateServicer 加到 server 中
calculate_pb2_grpc.add_CalculateServicer_to_server(CalculateServicer(), server)
# 让 server 跑在 port 50051 中
print 'Starting server. Listening on port 50051.'
server.add_insecure_port('[::]:50051')
server.start()
# 因为 server.start() 不会阻塞,添加睡眠循环以持续服务
try:
while True:
time.sleep(24 * 60 * 60)
except KeyboardInterrupt:
server.stop(0)
启动 gRPC server:
$ python server.py
Starting server. Listening on port 50051.
5. 创建 gRPC 客户端
client.py
# -*- coding: utf-8 -*-
import grpc
import calculate_pb2
import calculate_pb2_grpc
# 打开 gRPC channel,连接到 localhost:50051
channel = grpc.insecure_channel('localhost:50051')
# 创建一个 stub (gRPC client)
stub = calculate_pb2_grpc.CalculateStub(channel)
# 创建一个有效的请求消息 Number
number = calculate_pb2.Number(value=16)
# 带着 Number 去调用 Square
response = stub.Square(number)
print response.value
启动 gRPC client:
$ python client.py
4.0
最终的文件结构:
有疑问加站长微信联系(非本文作者)