跨语言的GRPC协议

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 【2月更文挑战第11天】

GRPC 首先满足二进制和跨语言这两条,二进制说明压缩效率高,跨语言说明更灵活。但是又是二进制,又是跨语言,这就相当于两个人沟通,你不但说方言,还说缩略语,人家怎么听懂呢?所以,最好双方弄一个协议约定文件,里面规定好双方沟通的专业术语,这样沟通就顺畅多了。


对于 GRPC 来讲,二进制序列化协议是 Protocol Buffers。首先,需要定义一个协议文件.proto。


Protocol Buffers 是一款压缩效率极高的序列化协议,有很多设计精巧的序列化方法。

对于 int 类型 32 位的,一般都需要 4 个 Byte 进行存储。在 Protocol Buffers 中,使用的是变长整数的形式。对于每一个 Byte 的 8 位,最高位都有特殊的含义。


如果该位为 1,表示这个数字没完,后续的 Byte 也属于这个数字;如果该位为 0,则这个数字到此结束。其他的 7 个 Bit 才是用来表示数字的内容。因此,小于 128 的数字都可以用一个 Byte 表示;大于 128 的数字,比如 130,会用两个字节来表示。


对于每一个字段,使用的是 TLV(Tag,Length,Value)的存储办法。


其中 Tag = (field_num << 3) | wire_type。field_num 就是在 proto 文件中,给每个字段指定唯一的数字标识,而 wire_type 用于标识后面的数据类型。

image.png

例如,对于 string author = 3,在这里 field_num 为 3,string 的 wire_type 为 2,于是 (field_num << 3) | wire_type = (11000) | 10 = 11010 = 26;接下来是 Length,最后是 Value 为“liuchao”,如果使用 UTF-8 编码,长度为 7 个字符,因而 Length 为 7。


在灵活性方面,这种基于协议文件的二进制压缩协议往往存在更新不方便的问题。例如,客户端和服务器因为需求的改变需要添加或者删除字段。


这一点上,Protocol Buffers 考虑了兼容性。在上面的协议文件中,每一个字段都有修饰符。比如:

  • required:这个值不能为空,一定要有这么一个字段出现;
  • optional:可选字段,可以设置,也可以不设置,如果不设置,则使用默认值;
  • repeated:可以重复 0 到多次。


由于基于 HTTP 2.0,GRPC 和其他的 RPC 不同,可以定义四种服务方法。


第一种,也是最常用的方式是单向 RPC,即客户端发送一个请求给服务端,从服务端获取一个应答,就像一次普通的函数调用。

rpc SayHello(HelloRequest) returns (HelloResponse){}


第二种方式是服务端流式 RPC,即服务端返回的不是一个结果,而是一批。客户端发送一个请求给服务端,可获取一个数据流用来读取一系列消息。客户端从返回的数据流里一直读取,直到没有更多消息为止。

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}


第三种方式为客户端流式 RPC,也即客户端的请求不是一个,而是一批。客户端用提供的一个数据流写入并发送一系列消息给服务端。一旦客户端完成消息写入,就等待服务端读取这些消息并返回应答。

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}


第四种方式为双向流式 RPC,即两边都可以分别通过一个读写数据流来发送一系列消息。这两个数据流操作是相互独立的,所以客户端和服务端能按其希望的任意顺序读写,服务端可以在写应答前等待所有的客户端消息,或者它可以先读一个消息再写一个消息,或者读写相结合的其他方式。每个数据流里消息的顺序会被保持。

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){}


如果基于 HTTP  2.0,客户端和服务器之间的交互方式要丰富得多,不仅可以单方向远程调用,还可以实现当服务端状态改变的时候,主动通知客户端。


GRPC 支持比较好的负载均衡器 Envoy。其实 Envoy 不仅仅是负载均衡器,它还是一个高性能的 C++ 写的 Proxy 转发器,可以配置非常灵活的转发规则。


无论是静态的,还是动态的,在配置里面往往会配置四个东西。


第一个是 listener。Envoy 既然是 Proxy,专门做转发,就得监听一个端口,接入请求,然后才能够根据策略转发,这个监听的端口就称为 listener。


第二个是 endpoint,是目标的 IP 地址和端口。这个是 Proxy 最终将请求转发到的地方。


第三个是 cluster。一个 cluster 是具有完全相同行为的多个 endpoint,也即如果有三个服务端在运行,就会有三个 IP 和端口,但是部署的是完全相同的三个服务,它们组成一个 cluster,从 cluster 到 endpoint 的过程称为负载均衡,可以轮询。


第四个是 route。有时候多个 cluster 具有类似的功能,但是是不同的版本号,可以通过 route 规则,选择将请求路由到某一个版本号,也即某一个 cluster。


如果是静态的,则将后端的服务端的 IP 地址拿到,然后放在配置文件里面就可以了。

如果是动态的,就需要配置一个服务发现中心,这个服务发现中心要实现 Envoy 的 API,Envoy 可以主动去服务发现中心拉取转发策略。

image.png

看来,Envoy 进程和服务发现中心之间要经常相互通信,互相推送数据,所以 Envoy 在控制面和服务发现中心沟通的时候,就可以使用 GRPC,也就天然具备在用户面支撑 GRPC 的能力。


Envoy 如果复杂的配置,都能干什么事呢?


一种常见的规则是配置路由策略。例如后端的服务有两个版本,可以通过配置 Envoy 的 route,来设置两个版本之间,也即两个 cluster 之间的 route 规则,一个占 99% 的流量,一个占 1% 的流量。


另一种常见的规则就是负载均衡策略。对于一个 cluster 下的多个 endpoint,可以配置负载均衡机制和健康检查机制,当服务端新增了一个,或者挂了一个,都能够及时配置 Envoy,进行负载均衡。


image.png

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
Kubernetes Linux API
[没接触过kubevirt?]15分钟快速入门kubevirt
什么是kubevirt? kubevirt是一个容器方式运行虚拟机的项目。`kubevirt`是附加`kubernetes`集群上的,它是通过 `CustomResourceDefinition(CRD)`部署到`Kubernetes API`变成资源对象。使用方式类似创建`deploy、pod`......这些资源清单。
5224 0
[没接触过kubevirt?]15分钟快速入门kubevirt
|
消息中间件 SQL 存储
超详细的RabbitMQ入门,看这篇就够了!
RabbitMQ入门,看这篇就够了
215786 67
|
6月前
|
人工智能 自然语言处理 程序员
产品测评 | AI编程界的集大成者——通义灵码AI程序员
通义灵码AI程序员是阿里云推出的一款基于先进自然语言处理和深度学习技术的编程助手,集成于VS Code和JetBrains IDEs中。它覆盖从前端到后端的开发流程,支持多文件级别的代码修改、单元测试生成、多版本快照管理等高级功能,显著提升开发效率和项目管理能力。开发者可通过对话式交互完成需求理解到产品发布的全过程,实现高效敏捷开发。最新2.0版本在代码生成、跨语言编程、单元测试自动生成及图生代码等方面有显著提升,进一步优化了用户体验。
|
缓存 JSON 负载均衡
http请求grpc服务的最终解决方案
所有的rpc协议遵守着一个万变不离其宗的定律:调用方与服务提供方有一套约定的报文解析格式。nodejs做代理,http报文组装成grpc报文,必须依赖.proto文件中定义的消息体
2151 0
http请求grpc服务的最终解决方案
|
SQL 存储 安全
SQL视图实验:创建、查询与管理技巧
在数据库管理系统中,视图(View)是一个虚拟表,其内容由查询定义
|
存储 分布式计算 安全
大数据存储技术(2)—— HDFS分布式文件系统
大数据存储技术(2)—— HDFS分布式文件系统
1599 0
|
缓存 UED 开发者
CDN的优缺点是什么呢
【4月更文挑战第21天】CDN提升网站访问速度和可用性,通过全球缓存服务器减轻源服务器负载,优化用户体验。然而,其成本较高,技术复杂,存在内容同步问题和对第三方服务的依赖。在使用CDN时需权衡利弊。
931 4
|
SQL 关系型数据库 MySQL
MySQL事务原理分析(ACID特性、隔离级别、锁、MVCC、并发读异常、并发死锁以及如何避免死锁)
MySQL事务原理分析(ACID特性、隔离级别、锁、MVCC、并发读异常、并发死锁以及如何避免死锁)
316 1
|
存储 Java 关系型数据库
沐歌保健院线上预约按摩系统的设计与实现(论文+源码)_kaic
本论文详细概述了沐歌保健院线上预约按摩系统设计实现的全过程,该系统基于Java语言、JSP技术设计等技术进行编写,运用 B/S 架构,采取MySQL数据库技术来存储必要信息。具有包括系统个人中心、用户管理、技师管理、排班管理、采购申请管理、项目管理、系统管理等功能模块。此系统允许三种身份登录:技师、管理人员、用户。用户可以预约下单自己需要的项目;技师则可以接单、查看排版表等信息来完成自己的职责;管理人员则是负责整体系统内信息的增删改查,使线下实体店和网络上的人员构成、项目排班的保持一致。