用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编程实现及时获取新邮件的方法示例
Aug 10 Python
Python列表删除的三种方法代码分享
Oct 31 Python
python 读文件,然后转化为矩阵的实例
Apr 23 Python
对Tensorflow中的变量初始化函数详解
Jul 27 Python
win7 x64系统中安装Scrapy的方法
Nov 18 Python
Python3.5文件修改操作实例分析
May 01 Python
解决Mac下使用python的坑
Aug 13 Python
python实现的批量分析xml标签中各个类别个数功能示例
Dec 30 Python
tensorflow 查看梯度方式
Feb 04 Python
python pprint模块中print()和pprint()两者的区别
Feb 10 Python
Python并发请求下限制QPS(每秒查询率)的实现代码
Jun 05 Python
Python 抓取数据存储到Redis中的操作
Jul 16 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代码
2006/12/06 PHP
PHP的SQL注入过程分析
2012/01/06 PHP
PHP实现ftp上传文件示例
2014/08/21 PHP
php实现编辑和保存文件的方法
2015/07/20 PHP
Yii 2.0中场景的使用教程
2017/06/02 PHP
在JavaScript中,为什么要尽可能使用局部变量?
2009/04/06 Javascript
js 函数的执行环境和作用域链的深入解析
2009/11/01 Javascript
jQuery中绑定事件的命名空间详解
2011/04/05 Javascript
Jquery实现仿腾讯娱乐频道焦点图(幻灯片)特效
2015/03/06 Javascript
js鼠标点击按钮切换图片-图片自动切换-点击左右按钮切换特效代码
2015/09/02 Javascript
用JS中split方法实现彩色文字背景效果实例
2016/08/24 Javascript
r.js来合并压缩css文件的示例
2018/04/26 Javascript
JS使用Dijkstra算法求解最短路径
2019/01/17 Javascript
jQuery子选择器与可见性选择器实例分析
2019/06/28 jQuery
微信小程序绘制图片发送朋友圈
2019/07/25 Javascript
微信小程序事件 bindtap bindinput代码实例
2019/08/26 Javascript
记录vue做微信自定义分享的一些问题
2019/09/12 Javascript
[13:21]DOTA2国际邀请赛采访专栏:RSnake战队国士无双,Fnatic.Fly
2013/08/06 DOTA
[38:30]2014 DOTA2国际邀请赛中国区预选赛 LGD-GAMING VS CIS 第一场2
2014/05/24 DOTA
[46:48]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第三局
2016/02/25 DOTA
Python读取ini文件、操作mysql、发送邮件实例
2015/01/01 Python
详解Django中Request对象的相关用法
2015/07/17 Python
python列表的常用操作方法小结
2016/05/21 Python
浅谈django的render函数的参数问题
2018/10/16 Python
Python列表的切片实例讲解
2019/08/20 Python
pytorch中tensor张量数据类型的转化方式
2019/12/31 Python
如何基于python实现归一化处理
2020/01/20 Python
Fashion Eyewear美国:英国线上设计师眼镜和太阳镜的零售商
2016/08/15 全球购物
荣耀商城:HIHONOR
2020/11/03 全球购物
.NET面试题:什么是反射
2016/09/30 面试题
课外访万家心得体会
2014/09/03 职场文书
迟到检讨书
2015/01/26 职场文书
幼儿园中班教师个人工作总结
2015/02/06 职场文书
逃出克隆岛观后感
2015/06/09 职场文书
2015年音乐教研组工作总结
2015/07/22 职场文书
Java获取e.printStackTrace()打印的信息方式
2021/08/07 Java/Android