gRPC学习与应用(1)

  • 一、gRPC简介[1]
    • 1.概述
    • 2.使用Protocol Buffers通信
      • 2.1 数据结构定义
      • 2.2 gRPC服务定义
  • 二、核心概念
    • 1.服务定义
    • 2.同步调用 vs. 异步调用
    • 3.RPC生命周期
    • 4.元数据
    • 5.通道
  • 参考资料

一、gRPC简介[1]

1.概述

gRPC是RPC(Remote Procedure Call)框架中的一种,是一个高性能开源通用的RPC框架。它使用Protocol buffers作为其接口定义语言(Interface Definition Launguage, IDL)以及信息交换格式,支持众多开发语言,包括C# / .NET、C++、Dart、Go、Java、Kotlin、Node、Objective-C、PHP、Python、Ruby等。

在gPRC里,客户端可以直接调用另一台不同机器上服务端应用的方法,就像调用本地对象一样,使得我们能够更容易地创建分布式应用和服务。

与其他多种RPC系统一样,gRPC也是通过定义“服务”以及“可以远程调用的方法及其参数与返回值”实现远程调用的(实际上也就是消息协议和远程调用接口)。这些接口在服务端被实现,以便处理客户端的远程调用。而客户端则保留有一个存根(stub),该存根提供服务端的可以被远程调用的相同的接口。实际上也就是对远程服务调用进行了代理封装,所有关于网络通信相关的内容在代理中进行处理。

gRPC的交互过程如下:代理向外部提供可以直接调用的方法接口(不同语言实现的接口),通过将接口调用转换为通信消息发送,再到服务端接收解析通信消息,在服务端完成相应方法调用,再将处理后的结果通过通信返回给客户端,客户端解析通信消息,将解析出的消息结果作为被调用方法的返回值返回给调用方。通过这样的过程,就实现了调用方像调用本地对象一样调用远程方法。

gRPC基本原理
gRPC的优势[2]

  • 性能: gRPC使用的Protocol Buffers在服务端和客户端上的序列化非常快。Protocol Buffers序列化后的消息体积很小,能够有效负载,这在移动应用程序等有限带宽场景中显得很重要。

  • 代码生成: 通过在服务器和客户端之间共享*.proto文件,可以从端到端生成消息和客户端代码。客户端的代码生成消除了客户端和服务器上的重复消息,并为您创建了一个强类型的客户端。无需编写客户端代码,可在具有许多服务的应用程序中节省大量开发时间。

  • 严格的规范: 该gRPC规范是规定有关gRPC服务必须遵循的格式。gRPC消除了争论并节省了开发人员的时间,因为gPRC在各个平台和实现之间是一致的。

  • 流: HTTP/2为长期的实时通信流提供了基础。gRPC通过HTTP/2为流媒体提供一流的支持。

  • 截至时间/超时和取消: gRPC允许客户端指定他们愿意等待RPC完成的时间。该期限被发送到服务端,服务端可以决定在超出了限期时采取什么行动。(有助于实施资源使用限制)

gRPC的劣势

  • 浏览器支持有限,当下不可能直接从浏览器调用gRPC服务。gRPC Web是gRPC团队的一项附加技术,它在浏览器中提供有限的gRPC支持。但gRPC Web并非支持所有gRPC功能。不支持客户端和双向流,并且对服务器流的支持有限。

  • 传输数据时二进制流,且格式不可读。需要额外的工具来分析线路上的Protobuf有效负载,并手工编写请求。

gRPC适合使用场景

gRPC非常适合以下场景:

  • 微服务 - gRPC设计为低延迟和高吞吐量通信。gRPC非常适用于效率至关重要的轻型微服务。
  • 点对点实时通信 - gRPC对双向流媒体提供出色的支持。gRPC服务可以实时推送消息而无需轮询。
  • 多语言混合开发环境 - gRPC工具支持所有流行的开发语言,使gRPC成为多语言开发环境的理想选择。
  • 网络受限环境 - 使用Protobuf(一种轻量级消息格式)序列化gRPC消息。gRPC消息始终小于等效的JSON消息。

gRPC不建议使用场景

在以下场景中,建议使用其他框架而不是gRPC:

  • 浏览器可访问的API - 浏览器不完全支持gRPC。gRPC-Web可以提供浏览器支持,但它有局限性并引入了服务器代理。
  • 广播实时通信 - gRPC支持通过流媒体进行实时通信,但不存在向已注册连接广播消息的概念。例如,在应该将新聊天消息发送到聊天室中的所有客户端的聊天室场景中,需要每个gRPC呼叫以单独地将新的聊天消息流传输到客户端。对于这种场景,SignalR是这种情况的有用框架。SignalR具有持久连接的概念和对广播消息的内置支持。
  • 进程间通信 - 进程必须承载HTTP/2服务才能接受传入的gRPC调用。对于Windows,进程间通信管道是一种快速,轻量级的通信方法。

2.使用Protocol Buffers通信

gRPC默认使用谷歌成熟的开源协议Protocol Buffers来序列化结构化数据(尽管gRPC也可以使用类似JSON的数据格式)。

相比较而言,Protobuf有如下优点[3]

  • 足够简单
  • 序列化后体积很小:消息大小只需要XML的1/10 ~ 1/3
  • 解析速度快:解析速度比XML快20 ~ 100倍
  • 多语言支持
  • 更好的兼容性,Protobuf设计的一个原则就是要能够很好的支持向下或向上兼容

protobuf 有2个版本,默认版本是proto2,如果需要proto3,则需要在非空非注释第一行使用 syntax = "proto3" 标明版本。相比于proto2版本,proto3略微简化了语法、提供了一些新的特性,并支持了更多语言。

2.1 数据结构定义

使用Protocol Buffers的第一步是在以.proto为后缀的proto文件中定义所需要传输数据的结构。Protocol Buffers数据是按照消息的结构进行结构化的,每一个消息都是由一系列键值对构成的小的信息单元,例如:

message Person {string name = 1;int32 id = 2;bool has_ponycopter = 3;
}

采用上述格式定义好数据结构后,在能够使用之前,我们还需要使用protoc编译指令,对上述数据结构进行编译,将其编译为我们所选的编程语言可以用来访问数据的类。这个编译成的类,可以实现对域值(field)的访问以及结构数据的序列化(编译成字节)和反序列化(从字节解析)。

2.2 gRPC服务定义

与数据结构的定义类似,gRPC服务在以.proto为后缀的proto文件中定义,包括参数和返回值类型(数据结构)的定义,例如

// Greeter服务定义
service Greeter {// SayHello方法定义(参数类型、返回值类型)rpc SayHello (HelloRequest) returns (HelloReply) {}
}// 服务参数数据结构定义
message HelloRequest {string name = 1;
}// 服务返回值数据结构定义
message HelloReply {string message = 1;
}

通过使用protoc对上述proto文件进行编译,将得到生成的gRPC客户端和服务端源码,以及可以用于填充、序列化和检索消息类型的常规protocol buffer代码。

二、核心概念

1.服务定义

在前面,我们介绍了gRPC中数据结构和服务的定义(在以.proto为后缀的proto文件中),gRPC支持四种服务方法的定义:

gRPC服务支持所有流组合:

(1)一元(没有流媒体)

简单rpc 这就是一般的rpc调用,一个请求对象对应一个返回对象。客户端发起一次请求,服务端响应一个数据,即标准RPC通信。

rpc SayHello(HelloRequest) returns (HelloResponse);

(2)服务器到客户端流(客户端流式rpc)

客户端传入多个请求对象,服务端返回一个响应结果。应用场景:物联网终端向服务器报送数据。

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

(3)客户端到服务器流(服务端流式rpc)

一个请求对象,服务端可以传回多个结果对象。服务端流 RPC 下,客户端发出一个请求,但不会立即得到一个响应,而是在服务端与客户端之间建立一个单向的流,服务端可以随时向流中写入多个响应消息,最后主动关闭流,而客户端需要监听这个流,不断获取响应直到流关闭。应用场景举例:典型的例子是客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端。

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

(4)双向流媒体(双向流式rpc)

结合客户端流式rpc和服务端流式rpc,可以传入多个对象,返回多个响应对象。应用场景:聊天应用。

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

2.同步调用 vs. 异步调用

同步RPC调用将阻塞直至调用响应从服务端到达,是最为接近过程调用的方式。然而由于网络内生是异步的,并且在很多场景下,非阻塞式调用是十分有用的。因此,gRPC对大多数编程语言的API接口同时支持同步调用异步调用模式。

3.RPC生命周期

四种流组合模式下的RPC生命周期参见参考资料[1]中关于RPC生命周期部分的介绍,其中:

  • 一元(没有流媒体)模式下,交互过程与传统的socket通信基本类似。

  • 服务端流式rpc模式下,服务端会向客户端发送一系列响应消息后,其向客户端发送状态详细信息(包括状态码和可选的状态消息)以及可选的结尾元数据。

  • 客户端流式rpc模式下,客户端会发送一系列消息到服务端,服务端通过单一消息响应客户端(包括状态详细信息以及可选的结尾元数据),但也可能不会等到收完客户端发送的所有消息。

  • 双向流式rpc模式下,调用过程从客户端激活调用方法初始,服务端接收客户端的元数据、方法名称以及截止时间。而后,服务端可以选择是否发送初始元数据或者等待客户端开始发送消息流(因具体应用而异)。

关于截止时间和超时:gRPC允许客户端通过DEADLINE_EXCEEDED错误设置RPC等待时间,同时,支持服务端查询一个RPC过程是否超时或者还剩下多少时间。

4.元数据

元数据是特定RPC调用的信息(如身份验证详细信息),其形式为键值对列表,其中键是字符串,值通常是字符串,但也可以是二进制数据。

元数据对gRPC本身是不透明的——它允许客户端向服务器提供与调用相关的信息,反之亦然。对元数据的访问取决于语言。

5.通道

gRPC通道提供到指定主机和端口上的gRPC服务器的连接,在创建客户端存根时使用。客户端可以指定通道参数来修改gRPC的默认行为,例如打开或关闭消息压缩。通道具有状态,包括connectedidle。gRPC如何处理关闭通道取决于语言。某些语言还允许查询通道状态。

通过上述学习,我们大致上了解了gRPC的基本情况、核心概念以及使用方式。下面,我们将通过实际开发进一步了解和研究gRPC的使用。

参考资料

[1] Introduction to gRPC | gRPC

[2] GRPC简介 - 知乎 (zhihu.com)

[3] Google Protobuf简明教程 - 简书

gRPC学习与应用(1)相关推荐

  1. gRPC学习之六:gRPC-Gateway集成swagger

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos gRPC学习系列文章链接 在CentOS7部署和设置G ...

  2. gRPC学习记录(六)--客户端连接池

    对于客户端来说建立一个channel是昂贵的,因为创建channel需要连接,但是建立一个stub是很简单的,就像创建一个普通对象,因此Channel就需要复用,也就是说需要实现一个连接池应用.本文使 ...

  3. gRPC学习记录(一)--概念性知识

    前几天刚发了一个如何学习一门新技术,现在正好遇到了要学习的东西,因为重新找了工作,所以新公司使用的技术需要自己快速上手,那么快速学习就是必须掌握的一门技能了.下面根据之前的博文展示如何快速入门一门新技 ...

  4. gRPC学习记录(五)--拦截器分析

    对于此类调用拦截器是必不可少的,本篇就分析下拦截器的实现.(博主本来想分析源码的,但是水平不足,并发知识欠缺,看的不是很懂,哎,仍需努力),另外貌似不同版本有些差异,这里使用的是1.0.3版本. 1. ...

  5. gRPC学习记录(四)--官方Demo

    了解proto3后,接下来看官方Demo作为训练,这里建议看一遍之后自己动手搭建出来,一方面巩固之前的知识,一方面是对整个流程更加熟悉. 官方Demo地址: https://github.com/gr ...

  6. gRPC学习记录(二)--Hello World

    在上一篇的整体了解后,该篇则对应了快速上手,入门示例当然仍旧是Hello world,该一阶段不需要深究代码,所要求的的目的是先跑通,再回顾代码,然后分析需要什么知识,再去学什么. 1.Maven配置 ...

  7. gRPC 学习笔记

    简介 更多内容参考:https://www.grpc.io/docs/guides/ gRPC 是一个高性能.开源和通用的 RPC 框架,面向移动和 HTTP/2 设计.目前提供 C.Java 和 G ...

  8. Golang gRPC学习(04): Deadlines超时限制

    为什么要使用Deadlines# 当我们使用gRPC时,gRPC库关系的是连接,序列化,反序列化和超时执行.Deadlines 允许gRPC客户端设置自己等待多长时间来完成rpc操作,直到出现这个错误 ...

  9. gRPC学习Go版(一)

    文章目录 微服务入门 gRPC是什么 proto 服务定义 gRPC 优势 gRPC入门 简单使用 一元RPC 服务流RPC 客户流RPC 双工流RPC gRPC底层原理 RPC流 长度前缀的消息分帧 ...

最新文章

  1. python中关于sqlite3数据库更新数据的使用
  2. java的final修饰_java final 修饰符详解
  3. 基于Docker的Consul服务发现集群搭建
  4. Visual Studio 2019 16.1发布,更快更高效
  5. Taro+react开发(75):taro简介
  6. account表里有什么 银行_模拟一个银行账户类Account,账户类中包括所有者、账号、余额、账户总数、存款、取款等信息。_学小易找答案...
  7. PHP实现简单文件上传系统
  8. 你知道考的是平方数吗(记洛谷P1876题RE+WA的经历,Java语言描述)
  9. ubuntu窗口最小化消失,任务栏上无法找到的解决方法
  10. 【java】java jps 命令
  11. 【Git】error: RPC
  12. STM32开发小结--使用STM32F4串口的空闲中断模式+DMA接收不定长数据帧
  13. 建议收藏,最全ChatGPT 中文调教指南:提供各个领域的角色提示词(prompts)及使用技巧,当然也有不正经指南
  14. 工业级氯化锂2022年全球行业分析报告
  15. 哈工大计算机科学与技术硕士培养方案,计算机科学与技术学科硕士研究生培养方案哈工大计算机学院[文].pdf...
  16. sshpass报错Host key verification failed
  17. linux运行jar的几种方式
  18. jq获取页面中所有的a链接并执行下载功能
  19. kali linux通过ssh+putty来实现远程登录(亲测有效)
  20. python中else是什么意思中文翻译_else是什么意思

热门文章

  1. 2018.11.3 Nescafe18 T2 太鼓达人
  2. jQuery实例之表单验证
  3. jQuery Validate 表单验证框架
  4. idea 主题包网站
  5. 上海控安:车载总线渗透测试分析,构建网络安全防护体系
  6. 按键精灵物理实现重复点击
  7. 《新相亲大会》引发婚恋观讨论,珍爱网传递正向情感价值观
  8. 【CODE】Best Time to Buy and Sell Stock
  9. mysql编写倒计时_微信公众号开发,实现倒计时的一个功能(纯代码)
  10. python花瓣飘零_小白请上车 | Python抓取花瓣网高清美图