用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每隔N秒运行指定函数的方法
Mar 16 Python
Python多线程编程(二):启动线程的两种方法
Apr 05 Python
Python简单遍历字典及删除元素的方法
Sep 18 Python
Python实现简单遗传算法(SGA)
Jan 29 Python
python微信公众号开发简单流程
Mar 23 Python
推荐10款最受Python开发者欢迎的Python IDE
Sep 16 Python
深入了解和应用Python 装饰器 @decorator
Apr 02 Python
python3读取图片并灰度化图片的四种方法(OpenCV、PIL.Image、TensorFlow方法)总结
Jul 04 Python
python基于Selenium的web自动化框架
Jul 14 Python
Django app配置多个数据库代码实例
Dec 17 Python
python实现一个猜拳游戏
Apr 05 Python
详解python polyscope库的安装和例程
Nov 13 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
source.php查看源文件
2006/12/09 PHP
DedeCMS 核心类TypeLink.class.php摘要笔记
2010/04/07 PHP
解析PHP汉字转换拼音的类
2013/06/18 PHP
PHP检测数据类型的几种方法(总结)
2017/03/04 PHP
基于thinkphp6.0的success、error实现方法
2019/11/05 PHP
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
批量实现面向对象的实例代码
2013/07/01 Javascript
使用jQuery或者原生js实现鼠标滚动加载页面新数据
2016/03/06 Javascript
使用jQuery实现Web页面换肤功能的要点解析
2016/05/12 Javascript
BootStrap+Angularjs+NgDialog实现模式对话框
2016/08/24 Javascript
fckeditor部署到weblogic出现xml无法读取及样式不能显示问题的解决方法
2017/03/24 Javascript
jQuery动画_动力节点节点Java学院整理
2017/07/04 jQuery
js实现首屏延迟加载实现方法 js实现多屏单张图片延迟加载效果
2017/07/17 Javascript
新手简单了解vue
2019/05/29 Javascript
Vue 实现复制功能,不需要任何结构内容直接复制方式
2019/11/09 Javascript
[10:53]2018DOTA2国际邀请赛寻真——EG
2018/08/11 DOTA
[04:10]2018年度CS GO玩家最喜爱的主播-完美盛典
2018/12/16 DOTA
Python入门之modf()方法的使用
2015/05/15 Python
利用Python实现命令行版的火车票查看器
2016/08/05 Python
Python3实现购物车功能
2018/04/18 Python
Django 日志配置按日期滚动的方法
2019/01/31 Python
python版百度语音识别功能
2019/07/09 Python
Python企业编码生成系统之主程序模块设计详解
2019/07/26 Python
python词云库wordCloud使用方法详解(解决中文乱码)
2020/02/17 Python
在keras下实现多个模型的融合方式
2020/05/23 Python
Python 创建守护进程的示例
2020/09/29 Python
Python plt 利用subplot 实现在一张画布同时画多张图
2021/02/26 Python
CSS3 box-shadow属性实例详解
2020/06/19 HTML / CSS
Canvas与Image互相转换示例代码
2013/08/09 HTML / CSS
发现世界上最好的珠宝设计师:JewelStreet
2017/12/17 全球购物
高一历史教学反思
2014/01/13 职场文书
普通员工辞职信
2014/01/17 职场文书
个人欠款协议书范本2014
2014/11/02 职场文书
2014年变电站工作总结
2014/12/19 职场文书
详解Python+OpenCV绘制灰度直方图
2022/03/22 Python
MySQL 执行数据库更新update操作的时候数据库卡死了
2022/05/02 MySQL