title: grpc| python 实战 grpc
description: 只要代码可以跑起来, 很多难题都会迎刃而解. so, keep coding and stay hungry.
之前用 swoole 写 server 时就接触过 protobuf, 本来以为基于 protobuf 的 grpc, 上手起来会轻轻松松, 没想到结结实实的折腾了许久, 从 php 开始配置 grpc 需要的环境, 到无奈转到 grpc 最亲和 的 go 语言, 又无奈面对各种 go get 撞墙, 直到现在使用 python 语言, 终于 丝般顺滑 的跑完了官网 demo. 代码运行起来后, 之前 grpc 中不太理解的概念, 终于可以 会心一笑 了.
grpc 的基础: protobuf
grpc helloworld: python 实战 grpc 环境配置
grpc basic: grpc 4 种通信方式
grpc 的基础: protobuf
grpc 使用 protobuf 进行数据传输. protobuf 是一种数据交换格式, 由三部分组成:
proto 文件: 使用的 proto 语法的文本文件, 用来定义数据格式
proto语法现在有 proto2 和 proto3 两个版本, 推荐使用 proto3, 更加简洁明了
protoc: protobuf 编译器(compile), 将 proto 文件编译成不同语言的实现, 这样不同语言中的数据就可以和 protobuf 格式的数据进行交互
protobuf 运行时(runtime): protobuf 运行时所需要的库, 和 protoc 编译生成的代码进行交互
使用 protobuf 的过程:
编写 proto 文件 -> 使用 protoc 编译 -> 添加 protobuf 运行时 -> 项目中集成
更新 protobuf 的过程:
修改 proto 文件 -> 使用 protoc 重新编译 -> 项目中修改集成的地方
PS: proto3 的语法非常非常的简单, 上手 protobuf 也很轻松, 反而是配置 protoc 的环境容易卡住, 所以推荐使用 python 入门, 配置 protoc 这一步非常省心.
grpc helloworld: python 实战 grpc 环境配置
上面已经定义好了 grpc helloworld demo 所需的 proto 文件, 现在来具体看看 python 怎么一步步把 grpc helloworld 的环境搭建起来:
protobuf 运行时(runtime)
这一步很简单, 安装 grpc 相关的 python 模块(module) 即可
使用 protoc 编译 proto 文件, 生成 python 语言的实现
编译后生成的代码:
helloworld_pb2.py: 用来和 protobuf 数据进行交互
helloworld_pb2_grpc.py: 用来和 grpc 进行交互
最后一步, 编写 helloworld 的 grpc 实现:
服务器端: helloworld_grpc_server.py
客户端: helloworld_grpc_client.py
运行 python helloworld_grpc_server.py 和 python helloworld_grpc_client.py, 就可以看到效果了
grpc basic: 4 种通信方式
helloworld 使用了最简单的 grpc 通信方式: 类似 http 协议的一次 request+response.
根据不同的业务场景, grpc 支持 4 种通信方式:
客服端一次请求, 服务器一次应答
客服端一次请求, 服务器多次应答(流式)
客服端多次请求(流式), 服务器一次应答
客服端多次请求(流式), 服务器多次应答(流式)
官方提供了一个 route guide service 的 demo, 应用到了这 4 种通信方式, 具体的业务如下:
数据源: json 格式的数据源, 存储了很多地点, 每个地点由经纬度(point)和地名(location)组成
通信方式 1: 客户端请求一个地点是否在数据源中
通信方式 2: 客户端指定一个矩形范围(矩形的对角点坐标), 服务器返回这个范围内的地点信息
通信方式 3: 客户端给服务器发送多个地点信息, 服务器返回汇总信息(summary)
通信方式 4: 客户端和服务器使用地点信息 聊天(chat)
对应的 proto 文件: routeguide.proto:
proto 中想要表示流式传输, 只需要添加 stream 关键字即可
同样的, 使用 protoc 生成代码:
生成了 routeguide_pb2.py routeguide_pb2_grpc.py 文件, 和上面的 helloworld 对应
这里需要增加一个 routeguide_db.py, 用来处理 demo 中数据源(routeguide_db.json)文件:
处理 json 的过程很简单, 解析 json 数据得到由坐标点组成的数组
好了, 还剩下一个难题: 怎么处理流式数据呢?. 答案是 for-in + yield
客户端读取服务器发送的流式数据
客户端发送流式数据给服务器
完整的服务器端代码: routeguide_grpc_server.py: