高效性跨平台分布式软件开发技术——gRPC

文章目录

        • 1. gRPC(google Remote Procedure Call) 技术 —— 高效性地跨平台、跨语言开发
        • 2. 基于 python 实现 gRPC 框架
          • 2.1 一个 gPRC 项目必须包含的几大部分
          • 2.2 helloworld.proto 文件——定义全局可调用函数及其参数数据结构
          • 2.3 server.py 文件——实现服务器端的全局可调用函数
          • 2.4 client.py 文件——调用在服务器代码中实现的全局函数
          • 2.5 运行结果
        • 3. 基于gRPC技术搭建一个简单的Agent学习系统

相信不少人在做项目开发的时候都会遇到这样的问题:一套系统中不同部分的代码会部署在多个不同的设备平台上,多个平台间需要保证数据相连。对于分布式部署的系统来说,高效的通信直接决定了整个系统的性能。此外,由于平台的多样性,不同平台上所适合的编程语言也可能有所差异(如:c++、python、objective-c等)。为此,一门支持“跨平台”、“跨语言”的技术对于一个分布式部署的系统来说显得尤为重要。

1. gRPC(google Remote Procedure Call) 技术 —— 高效性地跨平台、跨语言开发

为了解决上述问题,google设计了一种远程系统调用技术,其将多个不同设备平台视为一个整体,保证了在一个设备上的代码能够对另一个设备上代码中的函数进行访问和调用,实现了多个平台之间的数据交互,且各设备间不需要约定使用同一种编程语言,这就是gRPC技术。例如,在服务器机器上使用c++实现好的函数,在客户端终端设备上可以直接使用Ruby调用,在另外一台客户端机器上也可以直接使用Android调用,很好的保证了“跨语言、跨平台”的开发流程。

要想实现跨平台的代码调用就必然涉及到平台间的数据通信问题,数据通信效率成为了系统性能的一个重要指标。gRPC基于protobuf设计了数据互通协议,保证了数据传输时的高效性和快速性。Protocol Buffers是一种数据格式,与XML、JSON类似,但比JSON和XML更加的高效和快速,在一些高性能且对响应速度有要求的数据传输场景非常适用。在使用JSON进行数据编译时,为了保证数据的易读性JSON是以文本的形式存储和传输的,这样一来导致进行数据交换时设备需要耗费大量的CPU在I/O动作上,从而影响整个传输速率。而protobuf不同于JSON,它会将字符串都进行序列化后再进行传输,即传输的是二进制数据,此外,protobuf是基于数字tag来标识各内容,而JSON则是以字符串来标识各内容的,因此protobuf在传输速率方面有着天然的优势。

// protobuf 基于数字来确定内容段
message Person {required string name = 1;required int32 age = 2;required string gender = 3; 
}// Json 基于字符串来确定内容段
{"name" : "Wang DaChui","age"  : "18","gender" : "Male"
}

2. 基于 python 实现 gRPC 框架

如上一节中的图片中所示,我们可以利用gRPC框架实现不同平台上的代码之间相互调用,这一节中,我们通过分别编写“服务器”和“客户端”这两个不同平台的代码来实现在客户端代码中调用服务器代码中的函数。为了编写方便,我们将服务器和客户端代码存放在同一个机器上的不同位置,等最后部署的时候再将代码分别部署到对应的设备平台上。

2.1 一个 gPRC 项目必须包含的几大部分

下图是一个最简单的 gRPC 项目需要包含的文件,我们先来看看这些文件分别有什么用:

  • helloworld.proto:该文件的作用是“定义服务器函数” + “定义函数参数的数据类型”。
  • helloworld_pb2.pyhelloworld_pb2_grpc.py: 这两个文件是由python的grpc_tools根据helloworld.proto文件自动生成的,这两个文件保证了客户端能够调用服务器端的函数,不用修改。
  • server.py:服务器(设备平台1)上的代码。
  • client.py:客户端(设备平台2)上的代码。

上述4个部分是一个最简单的grpc项目所包含的文件,接下来我们依次实现每一个部分中代码,搭建一个简单的grpc项目,使得我们能够在client.py代码中调用server.py中定义的函数。这里可能有人会有疑问,如果要让client.py能调用server.py中的函数,那直接把server.py写成一个类,再在client.py中import server不就好了吗?需要注意的是,在最终部署的时候server.py和client.py是会部署在不同的机器上的,那时候client.py的机器上是找不到server.py代码文件的,这里只是为了方便开发和讲解才把这两个文件放在同一个机器上。

2.2 helloworld.proto 文件——定义全局可调用函数及其参数数据结构

.proto文件中需要定义服务器中需要实现的全局可调用函数,以及这个函数的参数数据结构,由于我们想在服务器上实现一个客户端可以直接调用的加法器,那么在.proto文件中我们就需要明确定义这个“加法函数”,以及“加法函数”所接收的参数类型和返回值类型,helloworld.proto文件内容如下:

syntax = "proto3";service Adder{// 将全局可调用函数AddNumber在这里声明,第一个括号内是传入参数,第二个括号是返回值参数rpc AddNumber(AddRequest) returns (AddResponse) {}
}// 对全局函数AddNumber的输入参数AddRequest进行数据格式定义
message AddRequest{int32 Number1 = 1;int32 Number2 = 2;
}// 对全局函数AddNumber的返回值参数AddResponse进行数据格式定义
message AddResponse{string ResultString = 1;
}

编写完成后保存文件,在Terminal中运行:

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./helloworld.proto

运行成功后会在当前目录生成两个文件:helloworld_pb2.pyhelloworld_pb2_grpc.py

  • –python_out:该参数指定了helloworld_pb2.py文件的生成路径。
  • –grpc_python_out:该参数指定了helloworld_pb2_grpc.py文件的生成路径。
  • -I:该参数指定了.proto文件的存放路径。
  • ./helloworld.proto:.proto文件的文件名。
2.3 server.py 文件——实现服务器端的全局可调用函数

server.py文件用于实现在.proto文件中声明的那些全局可调用函数,例如我们在helloworld.proto文件中声明了一个AddNumber()函数,那么我们就需要在server.py文件中去亲自实现这个函数,server.py文件内容如下:

from concurrent import futures
import loggingimport grpcimport helloworld_pb2
import helloworld_pb2_grpc"""对应.proto文件中的service Adder类"""
class Adder(helloworld_pb2_grpc.AdderServicer):"""实现.proto文件中的AdderNumber函数,这里request参数类型和.proto文件中AddRequest类型一样"""def AddNumber(self, request, context):"""保证该函数的返回值和.proto文件中定义的AddResponse返回值类型一样"""return helloworld_pb2.AddResponse(ResultString="Result: %d" % (request.Number1 + request.Number2))def serve():server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))helloworld_pb2_grpc.add_AdderServicer_to_server(Adder(), server)server.add_insecure_port('[::]:50051')server.start()server.wait_for_termination()if __name__ == "__main__":logging.basicConfig()serve() 

在这个文件中最重要的部分就是Adder这个类,这个类是对.proto文件中的service Adder的实现,因此在.proto中service部分里定义的函数在这个Adder class中都必须要实现。AddNumber(self, request, context)函数就是其对应的实现,第二个参数request的类型和.proto中定义的AddRequest类型是一样的(这个request参数是在客户端调用这个函数时需要传入的),因此可以直接通过request.Number1 和 request.Number2来直接访问这两个整型数据。最后在函数返回的时候必须要保证值也是.proto中定义的返回值类型,最好的办法就是直接返回.proto文件中的这个对象,只是修改这个对象中的值ResultString即可。

2.4 client.py 文件——调用在服务器代码中实现的全局函数

当我们实现好了server.py中的函数后,我们就可以在客户端代码中调用这个全局函数了,在这里我们在client.py代码中去调用server.py代码中实现的Adder()函数,client.py的内容如下:

import loggingimport grpcimport helloworld_pb2
import helloworld_pb2_grpcdef run():"""建立通信管道"""with grpc.insecure_channel('localhost:50051') as channel:"""建立一个stub对象,通过这个对象我们就可以调用服务器端的函数了"""stub = helloworld_pb2_grpc.AdderStub(channel)"""调用stub.AddNumber()函数,要保证传入参数是.proto文件中的AddRequest对象"""response = stub.AddNumber(helloworld_pb2.AddRequest(Number1=1, Number2=2))print(response)if __name__ == "__main__":logging.basicConfigrun()

在客户端代码中首先要建立一个stub对象,该对象就是远程服务器对象,我们通过stub对象就可以访问远程服务器上实现的全部函数了。要注意的是,在传入参数里必须要和.proto文件中的传入对象完全保持一致,最好的办法还是传入一个.proto文件中所声明的对象,只是修改其中的值便可。

2.5 运行结果

依次在两个不同的Terminal中先后运行server.py和client.py,在client端的运行环境中看到成功调用了server端中的AddNumber()函数:

3. 基于gRPC技术搭建一个简单的Agent学习系统

使用gRPC技术可以方便的设计一个Agent学习系统,即仿真端负责仿真环境的数据计算,算法端负责Agent行为决策。我使用gRPC技术搭建了一个简单的机器人找钻石的学习系统,github地址:这里。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290345.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在VS中设置比较和谐的字体和颜色的方法

作者:朱金灿来源:http://blog.csdn.net/clever101先在studiostyl.es网站选择你喜欢的字体方案,我个人比较喜欢这款:Humane Studio,注意在网页上选择你使用VS版本,然后单击Downlaod this scheme就可以了&…

一个脚本实现全量增量备份,并推送到远端备份中心服务器

2019独角兽企业重金招聘Python工程师标准>>> 摘要 由于工作需要,刚好需要这样一个功能的脚本,主要解决: 1. 不想在crontab中调度两条备份任务,一个做全量一个做增量 2. 如果每小时做增量,凌晨4点做全量&…

地壳中元素含量排名记忆口诀_Nature:利用熔融包裹体的元素和同位素示踪俯冲带流体来源...

Nature:利用熔融包裹体的元素和同位素示踪俯冲带流体来源在汇聚板块边缘,大洋岩石圈通过俯冲作用携带挥发分(尤其是水)进入地幔。这些俯冲下去的水/流体控制着岩浆产物、地震活动、陆壳形成和资源成矿。但是,识别不同流体的来源(沉积物&#…

Windows 10开发基础——文件、文件夹和库(一)

Windows 10开发基础——文件、文件夹和库(一) 原文:Windows 10开发基础——文件、文件夹和库(一)主要内容: 1.枚举查询文件和文件夹 2.文本文件读写的三种方法——创建写入和读取文件 3.获得文件的属性 枚举查询文件和…

Sigmoid函数与逻辑回归

文章目录(1). Sigmoid函数的由来——伯努利分布的衍生物1.1 为什么会有 sigmoid 函数的出现?1.2 sigmoid 函数推导过程1.3 sigmoid 函数求导(2). 逻辑回归(Logistic Regression)2.1 逻辑回归算法的最终本质——求决策边界2.2 逻辑回归算法中的…

Avalonia跨平台入门第二十二篇之人脸检测

在前面分享的几篇中咱已经玩耍了Popup、ListBox多选、Grid动态分、RadioButton模板、控件的拖放效果、控件的置顶和置底、控件的锁定、自定义Window样式、动画效果、Expander控件、ListBox折叠列表、聊天窗口、ListBox图片消息、窗口抖动、语音发送、语音播放、语音播放问题、玩…

pkpm板按弹性计算还是塑性_PKPM中的S\R验算显红原因分析

PKPM软件砼结构施工图中的,梁的配筋面积中,SR验算,经常会有个别构件显红的情况。查了一下PKPM说明书,并没有针对此情况的详细说明。根据本人的实际经验,总结了一下解决此问题的主要方法:一.超筋SR的值显示为…

多智能体连续行为空间问题求解——MADDPG

目录1. 问题出现:连续行为空间出现2. DDPG 算法2.1 DDPG 算法原理2.2 DDPG 算法实现代码2.2.1 Actor & Critic2.2.2 Target Network2.2.3 Memory Pool2.2.4 Update Parameters(evaluate network)2.2.5 Update Parameters(targ…

在.NET 6 中如何创建和使用 HTTP 客户端 SDK

如今,基于云、微服务或物联网的应用程序通常依赖于通过网络与其他系统通信。每个服务都在自己的进程中运行,并解决一组有限的问题。服务之间的通信是基于一种轻量级的机制,通常是一个 HTTP 资源 API。从.NET 开发人员的角度来看,我…

ttl接地是高电平还是低电平_功放技术参数1——高电平

在汽车音响中的功放或者DSP再或者是DSP功放中我们都会遇到高电平信号或者低电平信号输入,我们该如何判断主机输出的到底是高电平信号还是低电平信号呢?我们可以用一个很简单的方法来鉴定,那就是主机输出能够直接驱动喇叭的为高电平信号输出&a…

MultiProcessing中主进程与子进程之间通过管道(Pipe)通信

Python 中 Multiprocessing 实现进程通信1. 如何建立主进程与子进程之间的通信管道?2. 为什么一定要将Pipe中的某些端close()?本文参考自:python 学习笔记 - Queue & Pipes,进程间通讯 1. 如何建立主进程与子进程之间的通信管道&#xf…

如何为 .NET 项目自定义强制代码样式规则

前言每个人都有自己的代码样式习惯:命名约定、大括号、空格、换行等。但是,作为一个团队来说,应该使用同样的代码样式规则。这样可以有效减少编译器的警告/建议,保证阅读代码的人员理解一致。今天我们介绍一种为单独的 .NET 项目定义代码样式…

我是如何帮助创业公司改进企业工作的

前段时间在一家创业公司实习,几十个人的团队,正处在规模逐渐扩大的阶段,但是整个公司的协作工作和日常管理却越来越麻烦,鉴于我以前对Saas和协作平台都有过一点研究,于是leader叫我去找一个“简单,好用&…

PHP单例模式(精讲)

2019独角兽企业重金招聘Python工程师标准>>> 首先我们要明确单例模式这个概念,那么什么是单例模式呢? 单例模式顾名思义,就是只有一个实例。作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行…

【QMIX】一种基于Value-Based多智能体算法

文章目录1. QMIX 解决了什么问题(Motivation)2. QMIX 怎样解决团队收益最大化问题(Method)2.1 算法大框架 —— 基于 AC 框架的 CTDE(Centralized Training Distributed Execution) 模式2.2 Agent RNN Netw…

增强型的for循环linkedlist_LinkedList的复习

先摘选一段Testpublic void test_LinkedList() { // 初始化100万数据 List list new LinkedList(1000000);// 遍历求和int sum 0;for (int i 0; i sum list.get(i); }}乍一看可能觉得没什么问题,但是这个遍历求和会非常慢。主要因为链表的数据结构…

3月更新来了!Windows 11正式版22000.556发布

面向 Windows 11 正式版用户,微软现已发布累积更新 KB5011493,更新后版本号升级至 Build 22000.556。主要变化1.微软正在改变 Windows 11 "开始"菜单中推荐模块有关 Office 文件的打开方式。如果文件被同步到 OneDrive,“开始”菜单…

[C/C++]重读《The C Programming Language》

第一次读这本书的时候是大三初,现在打算重读一遍!。 第一章 导言 1. 学习一门新程序设计语言的唯一途径就是用它来写程序。 2. 每个程序都从main函数的起点开始执行。 3. 在C语言中,所有变量必须先声明后使用。 4. C语言中的基本数据类型的大…

115怎么利用sha1下载东西_618“甩”度娘,拥抱115,体验和价格才是王道

网盘价钱​前天618,圈子里的朋友几乎都“甩”了度娘一巴掌,我才知道115搞活动,由原来500元1年的钻石会员,变成500元3年,算起来每天不到0.5元,确实比度娘实惠了很多,而且活动持续到6月底。自从发…

安装宝塔面板

安装宝塔面板: 1. 宝塔面板网站: https://www.bt.cn/ 2.安装教程 https://www.bt.cn/bbs/thread-1186-1-1.html 3.1 使用远程工具连接执行以下命令 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install.sh &&…