GRPC学习笔记

GRPC学习笔记

1 GRPC简介

1.1 定义

gRPC(Google Remote Procedure Call,Google远程过程调用)协议是谷歌发布的基于HTTP2协议承载的高性能、通用的RPC开源软件框架,提供了支持多种编程语言的、对网络设备进行配置和管理的方法。

1.2 目的

随着网络复杂化,服务之间远程调用的普遍使用,对远程调用工具的需求也越迫切,gRPC协议应运而生。基于gRPC协议实现对设备的管理已经应用在Telemetry订阅管理,且可以满足大规模、高性能的网络监控需求,逐渐在业界广泛使用。另外,基于gRPC协议实现对设备的查询和配置管理,以便获取设备的异常信息,及时进行网络收敛和业务切换,避免大量丢包导致的业务中断。于是设备提供了一种通过gRPC方式来管理设备的方法,包括配置、查询和能力获取三个方法。这些方法是通过设备和采集器对接,实现采集设备数据的功能。

2 GRPC原理

2.1 GRPC协议框架

2.1.1 gRPC协议栈分层

协议栈分层外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

各层详细说明

层次说明
TCP层底层通信协议,基于TCP连接。
TLS层该层是可选的,基于TLS加密通道。
HTTP2层gRPC承载在HTTP2协议上,利用了HTTP2的双向流、流控、头部压缩、单连接上的多路复用请求等特性。
gRPC层远程过程调用,定义了远程过程调用的协议交互格式。
编码层gRPC通过编码格式承载数据,包括GPB(Google Protocol Buffer)编码格式、JSON(JavaScript Object Notation)编码格式。
数据模型层业务模块的数据。通信双方需要了解彼此的数据模型,才能正确调用信息。当前设备提供了订阅、配置、查询业务模块。
2.2.2 GRPC网络架构

gRPC采用客户端和服务器模型,使用HTTP2协议传输报文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

gRPC网络的工作机制如下:

  • 服务器通过监测指定服务端口来等待客户端的连接请求。
  • 用户通过执行客户端程序登录到服务器。
  • 客户端调用.proto文件提供的gRPC方法发送请求消息。
  • 服务器回复应答消息。
2.2.3 Dial-in模式和Dial-out模式

设备在网络架构里支持Dial-in和Dial-out两种对接模式。

  1. Dial-in模式:设备作为gRPC服务器,采集器作为gRPC客户端。由采集器主动向设备发起gRPC连接并获取需要采集的数据信息或下发配置。Dial-in模式适用于小规模网络和采集器需要向设备下发配置的场景。

    Dial-in模式支持以下操作:

    • Subscribe操作:高速采集设备的接口流量统计、CPU和内存等数据信息。当前仅支持基于Telemetry技术的Subscribe操作。
    • Get操作:获取设备运行状态和运行配置。当前仅支持基于gNMI(gRPC Network Management Interface)规范的Get操作。
    • Capabilities操作:获取设备能力数据。当前仅支持基于gNMI规范的Capabilities操作。
    • Set操作:向设备下发配置。当前仅支持基于gNMI规范的Set操作。
  2. Dial-out模式:设备作为gRPC客户端,采集器作为gRPC服务器。设备主动和采集器建立gRPC连接,将设备上配置的订阅数据推送给采集器。Dial-out模式适用于网络设备较多的情况下,由设备主动向采集器提供设备数据信息。Dial-out模式只支持基于Telemetry技术的Subscribe操作。

2.2 基于GRPC的订阅原理

2.3 基于gNMI的gRPC数据处理

gRPC支持通过gNMI(gRPC Network Management Interface)规范定义Capabilities、Set和Get、Subscribe方法,为用户提供基于gRPC协议的数据配置与查询功能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.3.1 gNMI接口

gRPC支持Capabilities、Get、Set、Subscribe; gNMI的rpc接口如下

service gNMI {// Capabilities allows the client to retrieve the set of capabilities that// is supported by the target. This allows the target to validate the// service version that is implemented and retrieve the set of models that// the target supports. The models can then be specified in subsequent RPCs// to restrict the set of data that is utilized.// Reference: gNMI Specification Section 3.2rpc Capabilities(CapabilityRequest) returns (CapabilityResponse);// Retrieve a snapshot of data from the target. A Get RPC requests that the// target snapshots a subset of the data tree as specified by the paths// included in the message and serializes this to be returned to the// client using the specified encoding.// Reference: gNMI Specification Section 3.3rpc Get(GetRequest) returns (GetResponse);// Set allows the client to modify the state of data on the target. The// paths to modified along with the new values that the client wishes// to set the value to.// Reference: gNMI Specification Section 3.4rpc Set(SetRequest) returns (SetResponse);// Subscribe allows a client to request the target to send it values// of particular paths within the data tree. These values may be streamed// at a particular cadence (STREAM), sent one off on a long-lived channel// (POLL), or sent as a one-off retrieval (ONCE).// Reference: gNMI Specification Section 3.5rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeResponse);
}

gnmi.proto文件链接:gnmi/proto/gnmi/gnmi.proto at master · openconfig/gnmi · GitHub

2.4 参考博客

CloudEngine 16800系列交换机 产品文档 (huawei.com)

3 gRPC的四种通信模式

  • RPC有四种通信⽅式,分别是:简单 RPC(Unary RPC)、服务端流式 RPC (Server streaming RPC)、客户端流式 RPC (Clientstreaming RPC)、双向流式 RPC(Bi-directional streaming RPC)。它们主要有以下特点:
服务类型特点
简单 RPC⼀般的rpc调⽤,传⼊⼀个请求对象,返回⼀个返回对象
服务端流式 RPC传⼊⼀个请求对象,服务端可以返回多个结果对象
客户端流式 RPC客户端传⼊多个请求对象,服务端返回⼀个结果对象
双向流式 RPC结合客户端流式RPC和服务端流式RPC,可以传⼊多个请求对象,返回多个结果对象

3.1 简单RPC

  • 简单rpc 这就是⼀般的rpc调⽤,⼀个请求对象对应⼀个返回对象
  • 客户端发起⼀次请求,服务端响应⼀个数据,即标准RPC通信。
  • 这种模式,⼀个每⼀次都是发起⼀个独⽴的tcp连接,⾛⼀次三次握⼿和四次挥⼿!
  • 这个就是我们基础案例的示例,模式图如下

[image-20220514155737224](https://images.cnblogs.com/cnblogs_com/Mcoming/2385829/o_240318095709_20220514-image-20220514155737224 .png)

3.2 服务端流式RPC

  • 服务端流式rpc ⼀个请求对象,服务端可以传回多个结果对象

  • 服务端流 RPC 下,客户端发出⼀个请求,但不会⽴即得到⼀个响应,⽽是在服务端与客户端之间建⽴⼀个单向的流,服务端可以随时向流
    中写⼊多个响应消息,最后主动关闭流,⽽客户端需要监听这个流,不断获取响应直到流关闭

  • 应⽤场景举例:

    • 典型的例⼦是客户端向服务端发送⼀个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端

[image-20220514155832935](https://images.cnblogs.com/cnblogs_com/Mcoming/2385829/o_240318095709_20220514-image-20220514155832935 .png)

3.3 客户端流RPC

  • 客户端流式rpc 客户端传⼊多个请求对象,服务端返回⼀个响应结果
  • 应用场景如:物联⽹终端向服务器报送数据

[image-20220514155907457](https://images.cnblogs.com/cnblogs_com/Mcoming/2385829/o_240318095709_20220514-image-20220514155907457 .png)

3.4 双向流RPC

  • 双向流式rpc 结合客户端流式rpc和服务端流式rpc,可以传⼊多个对象,返回多个响应对象
  • 应⽤场景:聊天应⽤

[image-20220514194549273](https://images.cnblogs.com/cnblogs_com/Mcoming/2385829/o_240318095709_20220514-image-20220514194549273 .png)

3.5 实战

stream_grpc.proto 定义

syntax = "proto3";package example;service StreamService {rpc BidirectionalStream(stream ExampleMessage) returns (stream ExampleMessage);   // 双向流模式rpc ClientStream(stream ExampleMessage) returns (ExampleMessage);                 // 客户端流模式rpc ServerStream(ExampleMessage) returns (stream ExampleMessage);                 // 服务端流模式
}message ExampleMessage {string data = 1;
}

客户端代码

import time
import grpc
import pb.stream_grpc_pb2 as service_pb2
import pb.stream_grpc_pb2_grpc as service_pb2_grpcdef run():with grpc.insecure_channel('localhost:50051') as channel:stub = service_pb2_grpc.StreamServiceStub(channel)response_iterator = stub.BidirectionalStream(iter([service_pb2.ExampleMessage(data='Hello'),service_pb2.ExampleMessage(data='Hello2'), service_pb2.ExampleMessage(data='Hello2'), service_pb2.ExampleMessage(data='Hello4'), service_pb2.ExampleMessage(data='Hello5')]))for response in response_iterator:print(response.data)
def send_stream_data():for i in range(10) :yield service_pb2.ExampleMessage(data=f'client send data {i}')time.sleep(1)def ClientStream():with grpc.insecure_channel('localhost:50051') as channel:stub = service_pb2_grpc.StreamServiceStub(channel)response = stub.ClientStream(send_stream_data())print('返回结果', response.data)def ServerSteam():with grpc.insecure_channel('localhost:50051') as channel:stub = service_pb2_grpc.StreamServiceStub(channel)response = stub.ServerStream(service_pb2.ExampleMessage(data='Start'))for msg in response:print('返回结果', msg.data)def BothStream():with grpc.insecure_channel('localhost:50051') as channel:stub = service_pb2_grpc.StreamServiceStub(channel)response = stub.BidirectionalStream(send_stream_data())for msg in response:print('客户端收到:', msg.data)if __name__ == '__main__':# run()# ClientStream()# ServerSteam()BothStream()

服务端代码

import time
from concurrent import futures
import grpc
import pb.stream_grpc_pb2 as service_pb2
import pb.stream_grpc_pb2_grpc as service_pb2_grpcclass StreamService(service_pb2_grpc.StreamServiceServicer):def BidirectionalStream(self, request_iterator, context):for message in request_iterator:print('服务端收到:',message.data)# 处理接收到的消息# yield service_pb2.ExampleMessage(data=message.data + " response")for i in range(10):time.sleep(1)yield service_pb2.ExampleMessage(data=f'服务端响应给客户端 {i}')def ClientStream(self, request_iterator, context):for message in request_iterator:print(message.data)return service_pb2.ExampleMessage(data=message.data + " client stream,server not stream")def ServerStream(self, request, context):print(request)for i in range(10):print(context.is_active())time.sleep(1)print('给客户端发送数据:', i)yield service_pb2.ExampleMessage(data=f'服务端响应 {i}')print(context.is_active())def serve():server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))service_pb2_grpc.add_StreamServiceServicer_to_server(StreamService(), server)server.add_insecure_port('[::]:50051')server.start()try:server.wait_for_termination()except KeyboardInterrupt:server.stop(0)if __name__ == '__main__':serve()

3.6 参考博客

grpc python 实战 python grpc stream_mob64ca13faa4e6的技术博客_51CTO博客

gRPC的四种通信模式 - BigSun丶 - 博客园 (cnblogs.com)

server.stop(0)

if name == ‘main’:
serve()


### 3.6 参考博客[grpc python 实战 python grpc stream_mob64ca13faa4e6的技术博客_51CTO博客](https://blog.51cto.com/u_16213593/7315989)[gRPC的四种通信模式 - BigSun丶 - 博客园 (cnblogs.com)](https://www.cnblogs.com/Mcoming/p/18080564)

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

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

相关文章

跨部门协作中的沟通困境与平台建设策略——以软硬件研发为例

一、背景 在科技行业,跨部门合作的重要性不言而喻,然而实际工作中,经常会遭遇沟通不畅的现象。以软件与硬件研发部门为例,两者在产品研发过程中经常需要紧密协作,但却时常出现信息传递障碍。当你试图阐述观点时&#…

分类预测 | Matlab实现RIME-BP霜冰优化BP神经网络多特征分类预测

分类预测 | Matlab实现RIME-BP霜冰优化BP神经网络多特征分类预测 目录 分类预测 | Matlab实现RIME-BP霜冰优化BP神经网络多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.RIME-BP霜冰优化BP神经网络多特征分类预测(Matlab实现完整源码和数据&a…

【深度学习】YOLOv5,烟雾和火焰,目标检测,防火检测,森林火焰检测

文章目录 数据收集和数据标注查看标注好的数据的脚本下载yolov5创建 dataset.yaml训练参数开始训练yolov5n训练训练后的权重下载gradio部署 数据收集和数据标注 搜集数据集2w张。 pip install labelme labelme 然后标注矩形框和类别。 下载数据请看这里: https:…

数据结构(C):时间复杂度和空间复杂度

目录 🚀 0.前言 🚀 1.为何会有时间复杂度和空间复杂度的概念 🚀 2.时间复杂度 2.1初步时间复杂度 2.2大O表示法 2.2.1.O(N*N) 2.2.2.O(N) 2.2.3.O(1) 2.3最坏情况…

nginx配置挂载html

目标 很多软件的官方文档,在国内打开很慢,每次都得等很久,看到官方同时提供了html的包,所以想着挂载到本地nginx下,查看会方便很多。 下载官方html文档包,解压到documentation_htmls下 想添加新的文档也是…

springboot停机关闭前保证处理完请求

application.yml配置 server:shutdown: graceful // 处理完请求在关闭服务server:shutdown: immediate // 立刻关闭,默认 jvm关闭自带的回调

在vscode上面进行分支merge的记录

前言:在我们的项目中,有两个分支:master和liutielong。现在要将liutielong分支的改动merge到master分支中。 如果master分支已经更改了,所以要先pull(这是在git bash里面的命令)。 git pull origin master…

jvm(JVM快速入门、stack栈、堆、GC垃圾回收、Arthas)

文章目录 1. JVM快速入门1.1. 结构图1.2. 类加载器ClassLoader1.3. 执行引擎Execution Engine1.4. 本地接口Native Interface1.5. Native Method Stack1.6. PC寄存器(程序计数器)1.7. Method Area方法区 2. stack栈3. 堆3.1. 堆体系概述3.1.1. 新生区3.1.2. 老年代3.1.3. 永久代…

【JAVA】UDP与TCP套接字编程

目录 一、UDP数据报套接字编程 1、DatagramSocket API 2、DatagramPacket API 3、InetSocketAddress API 4、示例一 5、示例二 二、TCP流套接字编程 1、ServerSocket API 2、Socket API 3、TCP中的长短连接 4、示例一 5、示例二 一、UDP数据报套接字编程 1、Datag…

SpanBert学习

SpanBERT: Improving Pre-training by Representing and Predicting Spans 核心点 提出了更好的 Span Mask 方案,也再次展示了随机遮盖连续一段字要比随机遮盖掉分散字好;通过加入 Span Boundary Objective (SBO) 训练目标,增强了 BERT 的性…

虚假新闻检测——Adapting Fake News Detection to the Era of Large Language Models

论文地址:https://arxiv.org/abs/2311.04917 1.概论 尽管大量的研究致力于虚假新闻检测,这些研究普遍存在两大局限性:其一,它们往往默认所有新闻文本均出自人类之手,忽略了机器深度改写乃至生成的真实新闻日益增长的现…

消消乐算法总结

前言 最近在工作中遇到一个问题,做一个消消乐的demo项目,连续相同数目超过四个后就要消除。我在网上看了很多解决方案,有十字形,横向,纵向,梯形搜索。越看越迷糊。这不是用一个BFS就能解决的问题吗&#x…