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


Posted in Python onJuly 04, 2021

gRPC 是可以在任何环境中运行的现代开源高性能 RPC 框架。它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证。它也适用于分布式计算的最后一英里,以将设备,移动应用程序和浏览器连接到后端服务。

用Python编写简单的gRPC服务

grpc官网python参考:https://www.grpc.io/docs/languages/python/quickstart/
http://grpc.github.io/grpc/python/grpc.html

  • Python 3.5 or higher
  • pip version 9.0.1 or higher

安装gRPC相关的库
grpcio-tools主要用根据我们的protocol buffer定义来生成Python代码,官方解释是Protobuf code generator for gRPC。

#apt install python3-pip
pip install grpcio
pip install protobuf
pip install grpcio_tools

编写proto文件

proto是一个协议文件,客户端和服务器的通信接口正是通过proto文件协定的,可以根据不同语言生成对应语言的代码文件。

heartbeat.proto文件:

syntax = "proto3";

message HeartbeatRequest{
	string Host      = 1;
	int32  Mem       = 2;
	int32  Disk      = 3;
	int32  Cpu       = 4;
	int64  Timestamp = 5;
	int64  Seq       = 6;

}

message HeartbeatResponse{
	int32  ErrCode   = 1;
	string ErrMsg    = 2;
}

heartbeat_service.proto

syntax = "proto3";

import "heartbeat.proto";

// HeartBeatService
service HeartBeatService{
    rpc HeartBeat(HeartbeatRequest) returns(HeartbeatResponse){}
}

核心 就是一个 用于生成需要用到数据类型的文件;一个就是用于生成相关调用方法的类。 一个定义数据类型,一个用于定义方法。

通过proto生成.py文件

proto文件需要通过protoc生成对应的.py文件。protoc的下载地址 。下载解压之后,将解压目录添加到path的环境变量中。

pip install grpcio
install grpcio-tools
#pip  install --upgrade protobuf

注意:【下面命令是在proto文件所在的目录执行的,-I 用来指定proto的目录是 . 】

python -m grpc_tools.protoc -I=. --python_out=.. heartbeat.proto
python -m grpc_tools.protoc -I=. --grpc_python_out=.. heartbeat_service.proto
  • -I 指定proto所在目录
  • -m 指定通过protoc生成py文件
  • ?python_out生成py文件的输出路径
  • heartbeat.proto、heartbeat_service.proto为 输入的proto文件
  • 生成的文件名中 xxx_pb2.py 就是我们刚才创建数据结构文件,里面有定义函数参数和返回数据结构; xxx_pb2_grpc.py 就是我们定义的函数,定义了我们客服端rpc将来要调用方法。

编译客户端和服务端代码

服务端

#!/usr/bin/env python
# coding=utf-8
import sys
from concurrent import futures
import time

import grpc
from google.protobuf.json_format import MessageToJson

import heartbeat_service_pb2_grpc
import heartbeat_pb2
from lib.core.log import LOGGER


class HeartBeatSrv(heartbeat_service_pb2_grpc.HeartBeatServiceServicer):
    def HeartBeat(self, msg, context):
        try:
            # LOGGER.info(MessageToJson(msg, preserving_proto_field_name=True))
            body = MessageToJson(msg, preserving_proto_field_name=True)
            LOGGER.info("Get Heartbeat Request: %s", body)

            response = heartbeat_pb2.HeartbeatResponse()
            response.ErrCode = 0000
            response.ErrMsg = "success"

            return response
        except Exception as e:
            print("exception in heartbeat")
            LOGGER.error("RPC Service exception: %s", e)
            response = heartbeat_pb2.HeartbeatResponse()
            response.ErrCode = 500
            response.ErrMsg = "rpc error: %s" % e
            return response


def server(host, rpc_port):
    # 这里通过thread pool来并发处理server的任务
    # 定义服务器并设置最大连接数,concurrent.futures是一个并发库,类似于线程池的概念
    grpc_server = grpc.server(futures.ThreadPoolExecutor(max_workers=100))
    # 不使用SSL
    grpc_server.add_insecure_port('[::]' + ':' + str(rpc_port))
    # This method is only safe to call before the server is started.
    #  绑定处理器HeartBeatSrv(自己实现了处理函数)
    heartbeat_service_pb2_grpc.add_HeartBeatServiceServicer_to_server(HeartBeatSrv(), grpc_server)
    # 该方法只能调用一次, start() 不会阻塞
    # 启动服务器
    grpc_server.start()
    LOGGER.info("server start...")
    while 1:
        time.sleep(10)
    #grpc_server.wait_for_termination()


def main():
    try:
        LOGGER.info("begin start server")

        rpc_port = 8090
        host = "::"
        server(host, rpc_port)

    except Exception as e:
        LOGGER.error("server start error: %s", e)
        time.sleep(5)


if __name__ == '__main__':
    LOGGER.info(sys.path)
    main()

客户端

from time import sleep

import grpc

import heartbeat_pb2
import heartbeat_service_pb2_grpc
from lib.core.log import LOGGER


def run(seq):
    option = [('grpc.keepalive_timeout_ms', 10000)]
    #
    with grpc.insecure_channel(target='127.0.0.1:8090', options=option) as channel:
        # 客户端实例
        stub = heartbeat_service_pb2_grpc.HeartBeatServiceStub(channel)
        # stub调用服务端方法
        response = stub.HeartBeat(heartbeat_pb2.HeartbeatRequest(Host='hello grpc', Seq=seq), timeout=10)
        LOGGER.info("response ErrCode:%s", response.ErrCode)


if __name__ == '__main__':

    for i in range(1, 10000):
        LOGGER.info("i: %s", i)
        sleep(3)
        run(i)

参考

使用Python实现gRPC通信
参考URL: https://zhuanlan.zhihu.com/p/363810793
python grpc搭构服务
https://www.jianshu.com/p/10d9ca034567
python grpc 服务端和客户端调用demo
参考URL: https://blog.csdn.net/qq_42363032/article/details/115282405

到此这篇关于用Python编写简单的gRPC服务的文章就介绍到这了,更多相关Python gRPC服务内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
介绍Python中的文档测试模块
Apr 28 Python
python文件操作之目录遍历实例分析
May 20 Python
Python批量重命名同一文件夹下文件的方法
May 25 Python
python中zip和unzip数据的方法
May 27 Python
Flask框架中密码的加盐哈希加密和验证功能的用法详解
Jun 07 Python
Python全局变量用法实例分析
Jul 19 Python
Pandas读取并修改excel的示例代码
Feb 17 Python
python在回调函数中获取返回值的方法
Feb 22 Python
numpy.linalg.eig() 计算矩阵特征向量方式
Nov 29 Python
python使用gdal对shp读取,新建和更新的实例
Mar 10 Python
解决pip install psycopg2出错问题
Jul 09 Python
python 实现音频叠加的示例
Oct 29 Python
python中__slots__节约内存的具体做法
Jul 04 #Python
python中Matplotlib绘制直线的实例代码
Jul 04 #Python
C站最全Python标准库总结,你想要的都在这里
Python实现列表拼接和去重的三种方式
Jul 02 #Python
简单且有用的Python数据分析和机器学习代码
Jul 02 #Python
python常见的占位符总结及用法
Jul 02 #Python
Python合并pdf文件的工具
You might like
php通过ksort()函数给关联数组按照键排序的方法
2015/03/18 PHP
php 调用ffmpeg获取视频信息的简单实现
2017/04/03 PHP
style、 currentStyle、 runtimeStyle区别分析
2010/08/01 Javascript
人人网javascript面试题 可以提前实现下
2012/01/05 Javascript
JavaScript自定义DateDiff函数(兼容所有浏览器)
2012/03/01 Javascript
jquery实现图片灯箱明暗的遮罩效果
2013/11/15 Javascript
javascript简单实现表格行间隔显示颜色并高亮显示
2013/11/29 Javascript
JQuery中阻止事件冒泡几种方式及其区别介绍
2014/01/15 Javascript
jQuery实现表格行上移下移和置顶的方法
2015/05/22 Javascript
简述AngularJS的控制器的使用
2015/06/16 Javascript
Bootstrap图片轮播组件使用实例解析
2016/06/30 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
2016/12/16 Javascript
使用JavaScript为一张图片设置备选路径的方法
2017/01/04 Javascript
Vue2.0 vue-source jsonp 跨域请求
2017/08/04 Javascript
Vue-Router模式和钩子的用法
2018/02/28 Javascript
JS实现获取进今年第几天是周几的方法分析
2018/06/27 Javascript
详解Vue项目部署遇到的问题及解决方案
2019/01/11 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
2019/06/18 jQuery
Vue切换组件实现返回后不重置数据,保留历史设置操作
2020/07/21 Javascript
axios封装与传参示例详解
2020/10/18 Javascript
[01:14]2014DOTA2展望TI 剑指西雅图newbee战队专访
2014/06/30 DOTA
[04:41]2014DOTA2国际邀请赛 Liquid顺利突围晋级正赛
2014/07/09 DOTA
Python struct模块解析
2014/06/12 Python
Python简单删除列表中相同元素的方法示例
2017/06/12 Python
Python使用tkinter模块实现推箱子游戏
2019/10/08 Python
WoolOvers爱尔兰:羊绒、羊毛和棉针织品
2017/01/04 全球购物
西海岸男士和男童服装:Johnnie-O
2018/03/15 全球购物
为什么如下的代码int a=100,b=100;long int c=a * b;不能工作
2013/11/29 面试题
交通安全寄语大全
2014/04/08 职场文书
美国留学经济担保书
2014/05/20 职场文书
投资意向书
2014/07/30 职场文书
优秀高中学生评语
2014/12/30 职场文书
幼儿园小班个人总结
2015/02/12 职场文书
大学宣传委员竞选稿
2015/11/19 职场文书
关于antd tree 和父子组件之间的传值问题(react 总结)
2021/06/02 Javascript
一次SQL如何查重及去重的实战记录
2022/03/13 MySQL