自学内容网 自学内容网

c++grpc详解

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一.简介

  • gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言
    版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C,
    PHP 和 C# 支持.
  • gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等 特性。这
    些特性使得其在移动设备上表现更好,更省电和节省空间占用。
  • 在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法, 使得您
    能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念: 定义一个服务,指
    定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口, 并运行一个 gRPC 服务器来
    处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法
    在这里插入图片描述

支持的语言

c++ java Objective-C python Ruby Go C# Node.js

使用场景

  • 低延迟,高扩展的分布式系统
  • 与云服务器通信
  • 设计与语言无关的协议
  • 分层设计

特点

  • 跨平台,跨语言
  • 协议自由,可根据需求自己选择协议(json, XML,thirft)
  • 支持同步和异步
  • 可以取消请求和设置超时
  • 流处理,可以处理大型数据集

二.传输原理

在这里插入图片描述

  • 使用stub代理使用protobuf将数据序列化,再使用http2.0将数据发送给tcp
  • 选择使用HTTP2.0和protobuf大大提升了传输效率
  • 在这里插入图片描述

protobuf传输

  • protobuf是Goole开发的一种跨语言,跨平台,可扩展的序列化数据协议
  • protobuf传输速度快比JOSN,采用二进制序列化方式,
  • 早期的rpc使用JSON传输,现在基本都采用Protobuf的二进制传输
  • 差别在于Json是适合人阅读,protobuf适合机器

HTTP2.0

在这里插入图片描述

http2.0,相对于http1.0有以下几个改进:

  • 未改变HTTP语义
  • 引入帧,流的概念,可以区分多个请求和相应
  • 借助帧和流可以实现多路复用
  • 使用二进制编码,降低header空间占用

流和帧

  • HTTP1.1存在无法区分请求,只能串行发送
  • HTTP2.0提出流的概念,每个请求对应一个ID,来区分不同请求
  • 基于流又提出帧的概念,将数据分成多个帧,分割传输,而这多个帧都属于一个流
  • 通过这种二进制乱序的模式,解决了HTTP1.1的核心痛点,通过这种复用tcp连接的方式,不用再同时建立多个连接,提升了TCP利用效率

三.grpc的四种模式

1.一元RPC模式

一元 RPC 模式也被称为简单 RPC 模式。在该模式中,当客户端调用服务器端的远程方法时,客户端发送请求至服务器端并获得一个响应,与响应一起发送的还有状态细节以及元数据。

2.服务端流

在一元 RPC 模式中,gRPC 服务器端和 gRPC 客户端在通信时始终只有一个请求和一个响应。在服务器端流 RPC模式中,服务器端在接收到客户端的请求消息后,会发回一个响应的序列。这种多个响应所组成的序列也被称为“流”。在将所有的服务器端响应发送完毕之后,服务器端会以元数据的形式将其状态发送给客户端,从而标记流的结束。

  • 在protoc文件中定义方式
    在这里插入图片描述
  • 客户端流式代码
std::unique ptr<ClientReader<Feature>>reader(stub ->ListFeatures(&context,rect));
while(reader->Read(&feature))
{
std::cout<<"Found feature called "<< feature.name()
<<" ata"<<feature.location().latitude()
<<feature.location().longitude() << std::end
}
Status status =reader->Finish();
if(status.ok()){
std::cout<<"ListFeatures rpc succeeded."<< std::endl;
}else {
ListFeatures rpc failed."<< std::endl;
}
  • 服务端流式代码
StatusRecordRoute(Servercontext context,const routeguide::Rectangle rectangle,ServerWrite<Feature>*write)override
{
for (const Feature& f:featurelist )
{
writer->Write(f);
}
return status::OK;//流结束
}

3.客户端流

在客户端流 RPC模式中,客户端会发送多个请求给服务器端,而不再是单个请求。服务器端则会发送一个响应给客户端。但是,服务器端不一定要等到从客户端接收到所有消息后才发送响应。基于这样的逻辑,我们可以在接收到流中的一条消息或几条消息之后就发送响应,也可以在读取完流中的所有消息之后再发送响应。

  • 在protoc文件中定义方式
    在这里插入图片描述
  • 客户端代码
std::unique ptr<clientWriter<Point>>writer(stub ->RecordRoute(&context,&stats);
for(int i=0;i< kPoints; i++){
//

业务处理
//
writer->Write(f.location()
)

writer->WritesDone();
Status status = writer->Finish():
  • 服务端代码
StatusRecordRoute(Servercontextcontext,ServerReader<Point>*reader,,RouteSummary*summary) override{

while(reader->Read(&point)){
处理业务
}
return status::OK;//流结束
}

4.双向流

在双向流 RPC 模式中,客户端以消息流的形式发送请求到服务器端,服务器端也以消息流的形式进行响应。调用必须由客户端发起,但在此之后,通信完全基于gRPC客户端和服务器端的应用程序逻辑。
需要一个接受线程和发送线程·

  • 在protoc文件中定义方式在这里插入图片描述
Status RouteChat(Servercontext* context,ServerReaderWriter<RouteNote,RouteNote>* stream)override
{
RouteNote note;
while(stream->Read(&note)){
//业务处理

sheam->Write(n);
}
return status::0K;
}

四.基本流程

在这里插入图片描述
基本流程代码以及一元模式看grpc的简单使用


原文地址:https://blog.csdn.net/Nieweishan/article/details/142723900

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!