用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插入排序算法实例分析
Jul 03 Python
python简单线程和协程学习心得(分享)
Jun 14 Python
Python实现二维数组按照某行或列排序的方法【numpy lexsort】
Sep 22 Python
python登录并爬取淘宝信息代码示例
Dec 09 Python
简单了解什么是神经网络
Dec 23 Python
Python 实现「食行生鲜」签到领积分功能
Sep 26 Python
python按比例随机切分数据的实现
Jul 11 Python
Pycharm pyuic5实现将ui文件转为py文件,让UI界面成功显示
Apr 08 Python
python实现简单学生信息管理系统
Apr 09 Python
浅谈Python中re.match()和re.search()的使用及区别
Apr 14 Python
关于keras.layers.Conv1D的kernel_size参数使用介绍
May 22 Python
scrapy-splash简单使用详解
Feb 21 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采集时被封ip的解决方法
2010/08/29 PHP
PHP中for与foreach的区别分析
2011/03/09 PHP
PHP 异步执行方法,模拟多线程的应用分析
2013/06/03 PHP
table标签的结构与合并单元格的实现方法
2013/07/24 PHP
php5.3以后的版本连接sqlserver2000的方法
2014/07/28 PHP
php中ltrim()、rtrim()与trim()删除字符空格实例
2014/11/25 PHP
PHP的消息通信机制测试实例
2016/11/10 PHP
PHP基于socket实现客户端和服务端通讯功能
2017/07/13 PHP
PHP如何使用cURL实现Get和Post请求
2020/07/11 PHP
JavaScript Konami Code 实现代码
2009/07/29 Javascript
Mootools 1.2教程 滚动条(Slider)
2009/09/15 Javascript
jquery中this的使用说明
2010/09/06 Javascript
使用GruntJS构建Web程序之安装篇
2014/06/04 Javascript
jQuery实现的指纹扫描效果实例(附演示与demo源码下载)
2016/01/26 Javascript
nodejs+express实现文件上传下载管理网站
2017/03/15 NodeJs
vue-resource请求实现http登录拦截或者路由拦截的方法
2018/07/11 Javascript
vue-cli监听组件加载完成的方法
2018/09/07 Javascript
微信小程序 wepy框架与iview-weapp的用法详解
2019/04/10 Javascript
javascript实现图片轮播代码
2019/07/09 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
2019/11/17 Javascript
Vue优化:常见会导致内存泄漏问题及优化详解
2020/08/04 Javascript
适用于 Vue 的播放器组件Vue-Video-Player操作
2020/11/16 Javascript
动态实现element ui的el-table某列数据不同样式的示例
2021/01/22 Javascript
python之Character string(实例讲解)
2017/09/25 Python
Python线上环境使用日志的及配置文件
2019/07/28 Python
python中rb含义理解
2020/06/18 Python
pycharm-professional-2020.1下载与激活的教程
2020/09/21 Python
python实现测试工具(二)——简单的ui测试工具
2020/10/19 Python
美国一家主打母婴用品的团购网站:zulily
2017/09/19 全球购物
Python里面如何实现tuple和list的转换
2012/06/13 面试题
DTD的含义以及作用
2014/01/26 面试题
护理专业学生职业生涯规划范文
2014/03/11 职场文书
数学教育专业求职信
2014/07/22 职场文书
2019预备党员转正申请书模板2篇!
2019/08/07 职场文书
营销策划分析:怎么策划才能更好销量产品?
2019/09/04 职场文书
Pytest中conftest.py的用法
2021/06/27 Python