摘要:这篇文章主要是总结了一下这段时间学习gRPC的过程中遇到的一些问题和知识点
前言:本篇文章主要是总结了一下学习gRPC的过程中遇到的一些问题和知识点。
gRPC是啥?????
所谓RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从server/client模型。使用的时候客户端调用server端提供的接口就像是调用本地的函数一样。如下图所示就是一个典型的RPC结构图。

gRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。
特性
基于HTTP/2
HTTP/2 提供了连接多路复用、双向流、服务器推送、请求优先级、首部压缩等机制。可以节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。gRPC 的协议设计上使用了HTTP2 现有的语义,请求和响应的数据使用HTTP Body 发送,其他的控制信息则用Header 表示。
IDL使用ProtoBuf
gRPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议(类似于XML、JSON、hessian)。ProtoBuf能够将数据进行序列化,并广泛应用在数据存储、通信协议等方面。压缩和传输效率高,语法简单,表达力强。
多语言支持(C, C++, Python, PHP, Nodejs, C#, Objective-C、Golang、Java)
gRPC支持多种语言,并能够基于语言自动生成客户端和服务端功能库。目前已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它语言的版本正在积极开发中,其中,grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等语言,grpc-java已经支持Android开发。
应用场景
gRPC已经应用在Google的云服务和对外提供的API中,其主要应用场景如下:
- 低延迟、高扩展性、分布式的系统。
- 同云服务器进行通信的移动应用客户端。
- 设计语言独立、高效、精确的新协议。
- 便于各方面扩展的分层设计,如认证、负载均衡、日志记录、监控等。
gRPC通信方式
gRPC有四种通信方式:
1、 Simple RPC
简单rpc:这就是一般的rpc调用,一个请求对象对应一个返回对象。proto语法:
1 | rpc simpleHello(Person) returns (Result) {} |
2、Server-side streaming RPC
服务端流式rpc:一个请求对象,服务端可以传回多个结果对象。proto语法:
1 | rpc serverStreamHello(Person) returns (stream Result) {} |
3、Client-side streaming RPC
客户端流式rpc:客户端传入多个请求对象,服务端返回一个响应结果。proto语法:
1 | rpc clientStreamHello(stream Person) returns (Result) {} |
4、Bidirectional streaming RPC
双向流式rpc:结合客户端流式rpc和服务端流式rpc,可以传入多个对象,返回多个响应对象。proto语法:
1 | rpc biStreamHello(stream Person) returns (stream Result) {} |
Protobuf3语法
常用语法
1 | syntax = "proto3";// 文件首个非空、非注释的行必须表明protobuf的版本,默认是proto2 |
JSON映射
Proto3支持标准的JSON编码,使得在不同的系统直接共享数据变得简单。下表列出的是基础的类型对照。
在JSON编码中,如果某个值被设置为null或丢失,在映射为ProtoBuf的时候会转换为相应的默认值。在ProtoBuf中如果一个字段是默认值,在映射为JSON编码的时候,这个默认值会被忽略以节省空间。可以通过选项设置,使得JSON编码输出中字段带有默认值。
| proto3 | JSON | JSON example | Notes |
|---|---|---|---|
| message | object | {“fooBar”: v,”g”: null,…} | 生成JSON对象。 消息字段名称映射到lowerCamelCase并成为JSON对象键。 如果指定了json_name字段选项,则将指定的值用作键。解析器接受 lowerCamelCase名称(或json_name选项指定的名称)和原始proto字段名称。 null是所有字段类型的可接受值,并被视为相应字段类型的默认值。 |
| enum | string | “FOO_BAR” | 使用proto中指定的枚举值的名称。 解析器接受枚举名称和整数值。 |
| map<K,V> | object | {“k”: v, …} | 所有键都转换为字符串。 |
| repeated V | array | [v, …] | null被转换为空列表[] |
| bool | true, false | true, false | |
| string | string | “Hello World!” | |
| bytes | base64 string | “YWJjMTIzIT8kKiYoKSctPUB+” | JSON值将是使用带填充的标准base64编码编码为字符串的数据。 接受带有/不带填充的标准或URL安全base64编码。 |
| int32, fixed32, uint32 | number | 1, -10, 0 | JSON值将是十进制数。 接受数字或字符串。 |
| int64, fixed64, uint64 | string | “1”, “-10” | JSON值将是十进制字符串。 接受数字或字符串。 |
| float, double | number | 1.1, -10.0, 0, “NaN”, “Infinity” | JSON值将是一个或多个特殊字符串值“NaN”,“Infinity”和“-Infinity”。 接受数字或字符串。 指数表示法也被接受。 |
| Any | object | {“@type”: “url”, “f”: v, … } | 如果Any包含具有特殊JSON映射的值,则它将按如下方式转换: {“@ type”:xxx,“value”:yyy} 。 否则,该值将转换为JSON对象,并将插入 “@ type” 字段以指示实际数据类型。 |
| Timestamp | string | “1972-01-01T10:00:20.021Z” | 使用RFC 3339,其中生成的输出将始终被Z标准化并使用0,3,6或9个小数位。 也接受“Z”以外的偏移。 |
| Duration | string | “1.000340012s”, “1s” | 生成的输出始终包含0,3,6或9个小数位,具体取决于所需的精度,后跟后缀“s”。 接受的是任何小数位(也没有),只要它们符合纳秒精度并且需要后缀“s”。 |
| Struct | object | { … } | 任意JSON对象 |
| Wrapper types | various types | 2, “2”, “foo”, true, “true”, null, 0, … | Wrappers在JSON中使用与包装基元类型相同的表示形式,除了在数据转换和传输期间允许并保留 null . |
| FieldMask | string | “f.fooBar,h” | 见field_mask.proto. |
| ListValue | array | [foo, bar, …] | |
| Value | value | 任意JSON 值 | |
| NullValue | null | JSON null |

grpcurl的使用
下载grpcurl工具:
github地址:https://github.com/fullstorydev/grpcurl/releases/tag/v1.3.1 点击release下载对应的版本
Linux内核的系统下:./grpcurl -plaintext -d ‘{JSON_FROMAT_DATA}’ {ADDRESS}:{PORT} {SERVICE_NAME}.{METHOD_NAME}
Windows操作系统下:grpcurl -d {JSON_FROMAT_DATA} -plaintext {ADDRESS}:{PORT} {SERVICE_NAME}/{METHOD_NAME}
需要注意Windows操作系统下{JSON_FROMAT_DATA}需要转义,例如入参为{“aa”:1,”bb”:”zhangsan”} 需要写成 {"aa":1,"bb":"zhangsan"}
调用gRPC服务:
Linux系统下:./grpcurl -plaintext -d ‘{“name”:”zhangsan”}’ {ADDRESS}:{PORT} com.ypsx.项目名.client.service.HelloService.sayHello
Windows操作系统cmd命令行下:grpcurl.exe -d {"name":"zhangsan"} -plaintext {ADDRESS}:{PORT} com.ypsx.项目名.client.service.HelloService/sayHello
Windows操作系统PowerShell命令行下:grpcurl.exe -d ‘{"name":"zhangsan"}’ -plaintext ‘{ADDRESS}:{PORT}’ ‘com.ypsx.项目名.client.service.HelloService/sayHello’
成功返回:
1 | { |
参考文章:https://colobu.com/2017/03/16/Protobuf3-language-guide/
- 本文作者: th3ee9ine
- 本文链接: https://www.blog.ajie39.top/2021/05/05/GRPC笔记/
- 版权声明: 本博客所有文章除特别声明外,均采用 LICENSE 下的许可协议。转载请注明出处!