在Python中使用gRPC的方法示例
作者:Xin Qiu 发布时间:2021-02-02 16:20:21
本文介绍了在Python中使用gRPC的方法示例,分享给大家,具体如下:
使用Protocol Buffers的跨平台RPC系统。
安装
使用 pip
pip install grpcio
pip install grpcio-tools googleapis-common-protos
gRPC由两个部分构成,grpcio 和 gRPC 工具, 后者是编译 protocol buffer 以及提供生成代码的插件。
使用
编写protocol buffer
使用 gRPC 首先需要做的是设计 protocol buffer。新建一个 msg.proto
文件。
syntax = "proto3";
service MsgService {
rpc GetMsg (MsgRequest) returns (MsgResponse){}
}
message MsgRequest {
string name = 1;
}
message MsgResponse {
string msg = 1;
}
以上面的这个消息服务为例,首先是规定语法,这里使用的是 proto3
的语法。接着使用 service
关键字定义服务,gRPC 提供4种 RPC 类型的服务,这里定义的是第一种单一请求单一回应,类似普通的函数调用,其他的使用到了 stream
关键字,将其放在括号里,代表这个数据是流数据。这个以后再来研究,本次先设计一个简单的RPC。
之后定义两个 message
,一个是请求的结构,一个是回应的结果。 这里表示这个数据结构是字符串,protocol buffer 还可以定义为 int32,int64,double,float 等等。这里赋予的初值可以随便填写,实际使用中,会被赋予新的值。
生成接口代码
因为之前安装好了一些辅助插件,使用这里直接可以生成。
python -m grpc_tools.protoc -I . --pythoout=. --grpc_python_out=. msg.proto
这里会生成两个文件, msg_pb2.py
和 msg_pb2_grpc.py
。这两个文件是为后续的服务端和客户端所用。前者是定义了一些变量,例如 _MSGREQUEST
中就包含了请求函数的名字,可接受的变量,实际上还是 msg.proto
里定义的东西。
创建服务端
首先需要导入 RPC 必备的包,以及刚才生成的两个文件。
import grpc
import msg_pb2
import msg_pb2_grpc
因为 RPC 应该长时间运行,考虑到性能,还需要用到并发的库。
from concurrent import futures
import time
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
在 Server 中,主要是实现服务,按照 msg.proto
定义的,这里需要写一个服务类 MsgServicer
,这个类需要实现之前定义的 GetMsg
。
class MsgServicer(msg_pb2_grpc.MsgServiceServicer):
def GetMsg(self, request, context):
print("Received name: %s" % request.name)
return msg_pb2.MsgResponse(msg='Hello, %s!' % request.name)
GetMsg 接收到的请求是在 request
中, msg.proto
中定义的 name
就是 request.name
,接着在 GetMsg 中设计 msg.proto
中定义的 MsgResponse
。
之后实现启动服务的部分即可。
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
msg_pb2_grpc.add_MsgServiceServicer_to_server(MsgServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
通过并发库,将服务端放到多进程里运行。
完整 msg_server.py
代码如下
import grpc
import msg_pb2
import msg_pb2_grpc
from concurrent import futures
import time
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
class MsgServicer(msg_pb2_grpc.MsgServiceServicer):
def GetMsg(self, request, context):
print("Received name: %s" % request.name)
return msg_pb2.MsgResponse(msg='Hello, %s!' % request.name)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
msg_pb2_grpc.add_MsgServiceServicer_to_server(MsgServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
创建客户端
客户端相对简单一些,这里我写了一个简单的客户端。
import grpc
import msg_pb2
import msg_pb2_grpc
def run():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
with grpc.insecure_channel('localhost:50051') as channel:
stub = msg_pb2_grpc.MsgServiceStub(channel)
response = stub.GetMsg(msg_pb2.MsgRequest(name='world'))
print("Client received: " + response.msg)
if __name__ == '__main__':
run()
使用 grpc.insecure_channel('localhost:50051')
进行连接 服务端, 接着在这个 channel
上创建 stub
, 在 msg_pb2_grpc
里可以找到 MsgServiceStub
这个类相关信息。这个 stub
可以调用远程的 GetMsg
函数。 MsgRequest
中的 name
即 msg.proto
中定义的数据。在回应里可以得到 msg.proto
中定义的 msg
。
运行
首先运行 python msg_server.py
启动服务端,接着运行 python msg_client.py
机会看到客户端接收到了服务端传来的消息。以上就是一个简单的 RPC 的使用。
总结
这里只是简单的用了一下 gRPC,关于另外三种模式,还在摸索。比起gRPC,我感觉简单 RestFul 更讨我喜欢。
来源:http://xinqiu.me/2018/08/07/learn-grpc/


猜你喜欢
- 目录定时器概念实现一个简单的定时程序方案一方案二定时器概念什么是定时器呢?它是指从指定的时刻开始,经过一个指定时间,然后触发一个事件,用户可
- 字符串在内存中是不可变的,放在只读内存段,因此你可以使用str[0]来访问,但是不能使用str[0]='a'来修改。修改字符
- 目录生成迷宫走出迷宫可视化总结相信大家都玩过迷宫的游戏,对于简单的迷宫,我们可以一眼就看出通路,但是对于复杂的迷宫,可能要仔细寻找好久,甚至
- 如果你能很好的理解我下面的一句话,那这些都不是问题了。asp是服务器端语言,它的作用是动态生成客户端浏览器所能识别的html css jav
- 今天在用python3+ImageFont输出中文时,结果显示乱码# coding:utf-8from PIL import Image,
- 1、pyecharts介绍 Echarts是一款由百度公司开发的开源数据可视化JS库,pyecharts是一款使用python调用echar
- 前言这次开发微信抢票程序中,普通用户的身份是由微信管理的。当用户通过微信公众号(测试号)向后台发消息时,微信会将用户的身份标记为一个uniq
- 问题描述时间在我们日常的代码编写中会是经常出现的筛选或排序条件,尤其是一些特殊时间节点的时间显得尤为突出,例如昨天,当前日期,当前月份,当前
- 1.简介:facenet 是基于 TensorFlow 的人脸识别开源库,有兴趣的同学可以扒扒源代码:https://github.com/
- ECMAScript 3在Array.prototype中定义了一些很有用的操作数组的函数,这意味着这些函数作为任何数组的方法都是可用的。1
- python中获取字典的key列表和value列表 # -*- coding: utf-8 -*-# 定义一个字典dic = {'剧
- 要在用户浏览器上安装cookie,HTTP服务器向HTTP响应添加类似以下内容的HTTP报头:Set-Cookie:session=8345
- 1.在python文件下新建python文件,输入文件名后按Enter键生成,比如: one.py .2.简单输入python代码: pri
- 即使你没听说过“ * 六度分隔理论”,也很可能听过“凯文 • 贝肯 (Kevin Bacon)的六度分隔值游戏”。在这两个游戏中,目标都是
- 然后我们在Interactive Python prompt中测试了一下:>>> import subprocess &n
- max_redis.php<?phpset_time_limit (0);for($i=1;$i<=1050;$i++){exe
- 本文实例讲述了Python基于hashlib模块的文件MD5一致性加密验证。分享给大家供大家参考,具体如下:使用hashlib模块,可对文件
- 测试用例我们分别在用户数据库(testpage),tempdb中创建相似对象t1,#t1,并在tempdb中创建创建非临时表,然后执行相应的
- 简单的小练习,实现将一个指定列表中的数值进行转化,对于其中的非负数不作处理,对于负数需要转化为制定的数值,很简单就不多说了,下面是具体的实现
- It is much easier to criticize somebody else’s work than to create som