gRPC学习笔记

1. RPC基础概念

1.1 RPC

远程过程调用(Remote Procedure Call, RPC),一种进程间通信的模式,允许运行于一台计算机的程序调用另一个地址空间(通常为一个开放网络的一台计算机)的子程序,而程序员就像调用本地程序一样,无需额外地为这个交互作用编程(无需关注细节)。

1.2 微服务

微服务是一种开发软件的架构和组织方法,其中软件由通过明确定义的API进行通信的小型独立服务组成,这些服务围绕业务构建,每项服务执行单一功能。
采用微服务架构后,可以将业务组件封装为中台服务,通过RPC进行远程调用,有着方便复用、系统架构清晰的好处。此外,由于各组件独立运行的性质,可以针对各项服务单独进行更新、部署和扩展,以满足对应用程序特定功能的需求。
由于服务间通信频繁,需要采用轻量级的通信。随着微服务架构的流行,RPC框架渐渐地成为服务框架的一个重要部分。

1.3 Protocol Buffer (Protobuf)

RPC对通信性能(例如信息的编解码)有着很高的要求。Protocol Buffer,简称Protobuf,是Google开源的一个语言无关、平台无关的通信协议,有着跨语言、跨平台、高性能的优点。

1.4 gRPC

Google开源的一个高性能的RPC框架,使用基于protobuf的二进制协议进行通信,有着高性能、支持多语言、成熟且广泛使用等优点。

参考

https://zh.wikipedia.org/zh-cn/%E9%81%A0%E7%A8%8B%E9%81%8E%E7%A8%8B%E8%AA%BF%E7%94%A8
https://aws.amazon.com/cn/microservices/
https://yuyy.info/?p=1911

2. RPC与HTTP(或RESTful API) 比较?

  • RESTful API需要有确定的URL,不是所有场景下操作的对象都有URL,而RPC类似函数调用的形式可以覆盖这些场景。
  • RPC在报文大小和编解码速度上都更占优势。RPC往往使用更加高效的编解码协议,例如gRPC用的protobuf是自定义的二进制报文;RESTful API基于HTTP,往往是用json或者XML,虽然可读性更高但是数据包更大,解析更需时间,此外报文的头部字段也更长,效率较低。
  • RPC基于TCP协议,也可以基于HTTP协议。HTTP自然是基于HTTP
  • RPC往往是服务内部调用,RESTful API往往面向用户。

    参考

    https://juejin.cn/post/6869249088953843719

3. RPC架构组件

一个基本的RPC架构里面应该至少包含以下4个组件:
组件
说明
客户端 Client 服务调用方(服务消费者)
客户端存根 Client Stub 存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端
服务端存根 Server Stub 接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理
服务端 Server 服务的真正提供者

具体调用过程:

  1. 服务消费者(client客户端)通过调用本地服务的方式调用需要消费的服务;
  2. 客户端存根(client stub)接收到调用请求后负责将方法、入参等信息序列化(组装)成能够进行网络传输的消息体;
  3. 客户端存根(client stub)找到远程的服务地址,并且将消息通过网络发送给服务端;
  4. 服务端存根(server stub)收到消息后进行解码(反序列化操作);
  5. 服务端存根(server stub)根据解码结果调用本地的服务进行相关处理;
  6. 本地服务执行具体业务逻辑并将处理结果返回给服务端存根(server stub);
  7. 服务端存根(server stub)将返回结果重新打包成消息(序列化)并通过网络发送至消费方;
  8. 客户端存根(client stub)接收到消息,并进行解码(反序列化);
  9. 服务消费方得到最终结果;

而RPC框架的实现目标则是将上面的第2-10步完好地封装起来,也就是把调用、编码/解码的过程给封装起来,让用户感觉上像调用本地服务一样的调用远程服务。

调用过程

参考

https://juejin.cn/post/7055613735020265479

4. Protobuf定义服务

使用protobuf定义服务的包含以下几个步骤:首先通过一个.proto文件来定义服务,包含gRPC service、request以及response的类型;其次通过protobuf编译器protoc生成对应高级语言版本的服务类文件和消息类文件,

4.1 .proto文件定义服务

.proto文件包含三个部分:定义服务、请求类型和响应类型。定义服务的service代码块如下所示:

service {
    // ...
}

service块中需要定义服务类型,gRPC支持4种服务类型:

4.1.1 简单RPC (simple RPC)

简单RPC与通常的函数调用类似,客户端使用存根(stub)发送请求到服务器并等待响应返回。

rpc GetFeature(Point) returns (Feature) {}

4.1.2 服务端流式RPC (server-side streaming RPC)

服务端流式RPC在定义时需要在响应类型前插入stream关键字。在这种服务类型下,客户端发送请求到服务器,得到一个流作为返回,客户端通过读取流获得一系列消息,直到流内消息全部读完后结束。

rpc ListFeatures(Rectangle) returns (stream Feature) {}

4.1.3 客户端流式RPC (client-side streaming RPC)

客户端流式RPC在定义时需要在请求类型前插入stream关键字。在这种服务类型下,客户端使用流的方式发送一系列消息到服务器,完成发送后等待响应返回。客户端通过读取流获得一系列消息,直到流内消息全部读完后结束。

rpc RecordRoute(stream Point) returns (RouteSummary) {}

4.1.4 双向流式RPC (bidirectional streaming RPC)

双向流式RPC在定义时需要在请求和响应类型前都插入stream关键字。在这种服务类型下,两个流独立运行,客户端与服务端的读写顺序没有固定要求,例如服务器可以在收到客户端发来的所有消息后再开始响应,也可以读一条消息再响应一条消息。流中的消息顺序会被记录。

rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}

4.2 .proto文件定义消息

此外,proto文件还包括在定义服务的请求和响应时出现的所有消息类型,例如在上文中出现的Point类型的定义如下:

message Point {
  int32 latitude = 1;
  int32 longitude = 2;
}
知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇