Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >常用协议对比及 RPC 协议新形态探索

常用协议对比及 RPC 协议新形态探索

原创
作者头像
乐事
修改于 2021-06-25 03:03:18
修改于 2021-06-25 03:03:18
1.6K0
举报
文章被收录于专栏:日常笔记日常笔记

前言

协议是 RPC 的基础。数据在连接上以什么格式传输,服务端如何确定收到请求的大小,同一个连接上能不能同时存在多个请求,请求如果出错了应该怎么响应……这些都是需要协议解决的问题。

从定义上讲,协议通过定义规则、格式和语义来约定数据如何在网络间传输。RPC 需要通信的两端都能够识别同一种协议。数据在网络上以比特流的方式传输,如果本端的协议对端不识别,对端就无法从请求中获取到有用信息,就会出现鸡同鸭讲的情况,无法实现上层的业务需求。

一个简单的协议需要定义数据交换格式,协议格式和请求方式。

数据交换格式在 RPC 中也叫做序列化格式。常用的序列化有 JSON / Protobuf / Hessian 等,评价序列化优劣一般从三个维度:

  • 序列化后的字节数组大小
  • 序列化和反序列化速度
  • 序列化后的可读性

协议在选取序列化方式时,按照具体的需求在这三个维度中互相取舍。序列化后的数组越小,越节省网络流量,但序列化过程可能更消耗时间。JSON\XML 这类基于文本的序列化方式往往更容易被开发者接受,因为相比于一连传的字节数组,文本更容易被理解,在各层设备中都能比较容易的识别,但可读性提高的后果是性能大幅降低。

协议格式是和 RPC 框架紧密相关的,按照功能划分有两种:

  • 一种是紧凑型协议,只提供用于调用的简单元数据和数据内容;
  • 另外一种是复合型协议,会携带框架层的元数据用来提供功能上的增强,这类协议的一个代表就是 RSocket。

请求方式和协议格式息息相关,常见的请求格式有同步 Request/Response 和异步 Request/Response,区别是客户端发出一个请求后,是否需要同步等待响应返回。如果不需要等待响应,一个链接上就可以同时存在多个未完成的请求,这也被叫做多路复用。另外的请求模型有 Streaming ,在一次完整的业务调用中存在多次 RPC,每次都传输一部分数据,适合流数据传输。

有了这三个基本约定,就能实现一个简单的 RPC 协议了。

Dubbo3 的一个核心内容就是定义下一代 RPC 协议。除了基础的通信功能,新协议还应该具有以下特性:

  • 统一的跨语言二进制格式
  • 支持 Streaming 和应用层全双工调用模型
  • 易于扩展
  • 能够被各层设备识别

这里我们对比一些常用的协议,来探索新协议的形态。

HTTP/1.1

HTTP/1.1 应该是应用最广泛的协议,简单清晰的语法,跨语言以及对原生移动端的支持都让其成为了事实上最被广泛接受的 RPC 方案。

然而从 RPC 协议的诉求上讲, HTTP1.1 主要有以下几个问题

  • 队头阻塞(HOL)导致其在单连接的性能低下,尽管支持了 pipeline 但仍无法避免响应按序返回;
  • 基于文本的协议每次请求都会重复携带很多繁杂无用的头部信息,浪费带宽影响性能;
  • 纯粹的 Request/Response 请求模型,无法实现 Server Push,只能依靠客户端轮询,同样 Streaming 的全双工也是不安全的。

RESP

RESP 是 Redis 使用的通信协议,其简洁易于理解的格式也助力了 Redis 各语言客户端的快速发展。但是这种类似 HTTP/1.1 的协议也存在着同样的性能问题。

  • 序列化表达能力弱,通常还需要借助其他序列化方式辅助,然而协议中又不支持设置特定序列化方式,只能依靠客户端约定;
  • 同样存在队头阻塞问题,pipeline 无法从根本上解决单连接性能问题;
  • Pub/Sub 在单连接情况下也有数量瓶颈。

Dubbo2.0

Dubbo2.0 协议直接定义在 TCP 传输层协议上,为协议功能定义提供了最大的灵活性,但同时也正是因为这样明显的灵活性优势,RPC 协议普遍都是定制化的私有协议。

Dubbo 协议体 Body 中有一个可扩展的 attachments 部分,这给 RPC 方法之外额外传递附加属性提供了可能,是一个很好的设计。但是类似的 Header 部分,却缺少类似的可扩展 attachments,这点可参考 HTTP 定义的 Ascii Header 设计,将 Body Attachments 和 Header Attachments 做职责划分。

  • Body 协议体中的一些 RPC 请求定位符如 Service Name、Method Name、Version 等,可以提到 Header 中,和具体的序列化协议解耦,以更好的被网络基础设施识别或用于流量管控;
  • 扩展性不够好,欠缺协议升级方面的设计,如 Header 头中没有预留的状态标识位,或者像 HTTP 有专为协议升级或协商设计的特殊 packet;
  • Java 版本的代码实现上,不够精简和通用。如在链路传输中,存在一些语言绑定的内容;消息体中存在冗余内容,如 Service Name 在 Body 和 Attachments 中都存在。

HTTP/2.0

HTTP/2.0 保留了 HTTP/1 的所有语义,在保持兼容的同时,在通信模型和传输效率上做了很大的改进,主要也是为了解决 HTTP/1 中的问题。

  • 支持单条链路上的 Multiplexing,相比于 Request - Response 独占链路,基于 Frame 实现更高效利用链路,StreamId 提供了上下文状态,client 可以根据 StreamId 支持乱序 Response 返回;
  • 头部压缩 HPACK,基于静态表和动态表实现了 Header 缓存,减少传输数据量;
  • Request - Stream 语义,原生支持 Server Push 和 Stream 数据传输;
  • Binary Frame,二进制分帧,可以单独处理 Header 和 Data。

HTTP/2.0 虽然克服了以上问题,但也存在着一些争议点,比如在 TCP 的上层进行流量控制的必要性,以及对 HTTP 语义通过 HPACK 兼容是否过于繁琐复杂。

gRPC

相比较于一些框架将应用层协议构建在裸 TCP 上,gRPC 选择了 HTTP/2.0 作为传输层协议。通过对 Header 内容和 Payload 格式的限定实现上层协议功能。

下面是 gRPC 的一些设计理念:

  • Coverage & Simplicity,协议设计和框架实现要足够通用和简单,能运行在任何设备之上,甚至一些资源首先的如 IoT、Mobile 等设备;
  • Interoperability & Reach,要构建在更通用的协议之上,协议本身要能被网络上几乎所有的基础设施所支持;
  • General Purpose & Performant,要在场景和性能间做好平衡,首先协议本身要是适用于各种场景的,同时也要尽量有高的性能;
  • Payload Agnostic,协议上传输的负载要保持语言和平台中立;
  • Streaming,要支持 Request - Response、Request - Stream、Bi-Steam 等通信模型;
  • Flow Control,协议自身具备流量感知和限制的能力;
  • Metadata Exchange,在 RPC 服务定义之外,提供额外附加数据传输的能力。

在这样的设计理念指导下,gRPC 最终被设计为一个跨语言、跨平台、通用的协议。功能上基本已经完全具备或可以轻易扩展出需要的新功能。然而我们知道,软件工程没有银弹,相比较于裸 TCP 专有协议,极限性能上 gRPC 肯定是要差一些。但是对大部分应用来说,相比较于 HTTP/1.1 的协议,gRPC/HTTP2 已经在性能上取得了很大的进步,同时又兼顾了可读性。

序列化上,gRPC 被设计成保持 payload 中立,但实际的跨语言场景需要一个强规范的接口定义语言来保证序列化结果的一致。在 gRPC 的官方实现中,protobuf 和 json 分别用来支持性能场景和开发效率场景。从序列化方式的选择到协议的各维度比较,基于 gRPC 扩展出新的协议是最优的选择。

Dubbo3.0

Dubbo3.0 的协议基于 gRPC ,在应用层、异常处理、协议层负载均衡支持和 Reactive 支持上提供了扩展。主要有三个目标:

  • 在分布式大规模集群场景下,提供更完善的负载均衡,以获取更高性能和保证稳定性;
  • 支持 tracing/monitoring 等分布式标准扩展,支持微服务标准化以及平滑迁移;
  • Reactive 语义在协议层增强,能够提供分布式 back-pressure 能力和更完善的 Streaming 支持。

除了协议层的支持,Dubbo3.0 新协议还包括易用性方面的支持,包括同时支持 IDL compiler 和 Annotation Compiler。客户端将更完善地支持原生异步回调、Future 异步和同步调用,服务端将使用非反射调用,这十分显著地提升了客户端和服务端性能。从用户迁移的角度,Dubbo 框架将提供平滑的协议升级支持,力求尽可能少的改造代码或配置就能带来成倍的性能提升。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
RPC框架:从原理到选型,一文带你搞懂RPC
RPC系列的文章是我去年写的,当时写的比较散,现在重新进行整理。对于想学习RPC框架的同学,通过这篇文章,让你知其然并知其所以然,便于以后技术选型,下面是文章内容目录:
科控物联
2022/06/13
28.1K1
RPC框架:从原理到选型,一文带你搞懂RPC
带你手把手实操一个RPC框架
首先从个人成长角度,如果一个新时代码农能清楚的了解RPC框架所具备的要素,掌握RPC框架中涉及的服务注册发现、负载均衡、序列化协议、RPC通信协议、Socket通信、异步调用、熔断降级等技术,可以全方位的提升基本素质。
得物技术
2022/12/13
8370
带你手把手实操一个RPC框架
Dubbo 3.0.0正式发布:应用级服务注册,跨语言的RPC协议、更好支持Kubernetes!
自从 Apache Dubbo 在 2011 年开源以来,在一众大规模互联网、IT公司的实践中积累了大量经验后,Dubbo 凭借对 Java 用户友好、功能丰富、治理能力强等优点在过去取得了很大的成功,成为国内外热门主流的 RPC 框架之一。
程序猿DD
2021/07/13
1.2K0
Dubbo 3.0.0正式发布:应用级服务注册,跨语言的RPC协议、更好支持Kubernetes!
【RPC 专栏】从跨语言调用到 dubbo2.js
摘要: 原创出处 https://www.cnkirito.moe/dubbojs-in-qianmi/ 「老徐」欢迎转载,保留摘要,谢谢!
芋道源码
2018/07/31
8180
【RPC 专栏】从跨语言调用到 dubbo2.js
RPC协议底层原理与实现「建议收藏」
在一个典型RPC的使用场景中,包含了服务发现、负载、容错、 网络传输 、 序列化 等组件,其中RPC协议就指明了程序如何进行网络传输和序列化 。也就是说一个RPC协议的实现就等于一个非透明的RPC调用,如何做到的的呢?
全栈程序员站长
2022/08/30
1.3K0
RPC协议底层原理与实现「建议收藏」
关于RPC协议的通俗理解
作者:肖继潮 链接:http://www.zhihu.com/question/25536695/answer/31046384 来源:知乎 著作权归作者所有,转载请联系作者获得授权。
全栈程序员站长
2022/08/31
6450
终于有人把tcp、http、rpc和grpc总结完整了
随着微服务的迅速发展,各大互联网企业也投入到微服务的使用种。微服务最大的特点是,跨进程、跨服务、跨语言之间的调用,使得我们能够像调用本地类、函数一样。当微服务具备该特点,将我们复杂的业务拆分成不同的服务,服务之间在相互调用。这也是微服务为什么火的原因之一。
兔云小新LM
2023/04/27
11.5K0
终于有人把tcp、http、rpc和grpc总结完整了
RPC-整体概念
  RPC(Remote Procedure Call),即远程过程调用,是一种通过网络从远程计算机程序上请求服务而不需要了解底层网络技术的协议,实现调用远程主机上的方法就像调用本地方法一样。RPC协议在分布式系统中发挥重要的作用。
在周末
2019/08/26
5630
聊聊高性能 RPC框架 gRPC
RPC、gRPC、Thrift、HTTP,大家知道它们之间的联系和区别么?这些都是面试常考的问题,今天带大家先搞懂 RPC 和 gRPC。
码猿技术专栏
2023/05/01
1.9K0
聊聊高性能 RPC框架 gRPC
HTTP 与 RPC 接口区别
HTTP 与 RPC 接口是两种常见的接口通信协议。本文将会介绍它们的定义,区别和相同之处,应用场景以及目前的技术发展趋势,并给出接口代码示例和开发常用工具。
物立
2023/04/17
7650
HTTP 与 RPC  接口区别
什么是 gRPC ?
说的白话一点,可以这么理解:现在有两台服务器A和B。部署在A服务器上的应用,想调用部署在B服务器上的另一个应用提供的方法,由于不在一个内存空间,不能直接调用,需要通过网络来达到调用的效果。
KevinYan
2021/10/14
2.3K0
什么是 gRPC ?
HTTP和RPC的区别
RPC(即Remote Procedure Call,远程过程调用)和HTTP(HyperText Transfer Protocol,超文本传输协议),两者前者是一种方法,后者则是一种协议。两者都常用于实现服务,在这个层面最本质的区别是RPC服务主要工作在TCP协议之上(也可以在HTTP协议),而HTTP服务工作在HTTP协议之上。由于HTTP协议基于TCP协议,所以RPC服务天然比HTTP更轻量,效率更胜一筹。
Steve Wang
2022/04/13
12.9K0
HTTP和RPC的区别
《Dubbo进阶一》——RPC协议底层原理
在一个典型的RPC的使用场景中,包含了服务发现、负载、容错、序列化和网络传输等组件,其中RPC协议指明了程序如何进行序列化和网络传输,也就是说一个RPC协议的实现等于一个非透明的RPC调用。
全栈程序员站长
2022/08/30
7050
《Dubbo进阶一》——RPC协议底层原理
一个好的RPC框架需要有什么
今日推荐文章:https://cloud.tencent.com/developer/article/2017599?policyId=20240001&traceId=01jesmy38j9nrp142z5gzy1vqt RPC简介,文章从基础的RPC框架架构说起,详细介绍了RPC框架的通信流程看完后我相信会对本文有更加深入的了解
潋湄
2024/11/20
3360
一个好的RPC框架需要有什么
Nodejs之RPC协议简介
随着 Nodejs 的兴起,越来越多的 Web 服务中间层被搭建起来。如 Node 服务端渲染,BFF(Backend For Frontend))层,而 RPC 是远端过程调用,经常用于 BFF 层。最近,我打算写一个中间层,用 Nodejs 调用 Go 服务,除了可以简单用 http 调用之外,发现还有基于 RPC 的调用就研究了一下。
winty
2019/12/20
2.1K0
你为什么使用RPC
微服务架构语境下,我们经常会聊到 RPC协议、RPC框架 等名词,但其实很多同学并没有真正理解这些术语的含义,只是一个模糊的概念。
windealli
2023/10/13
3330
你为什么使用RPC
如何设计可向后兼容的RPC协议
HTTP协议(本文HTTP默认1.X)跟RPC协议又有什么关系呢?都属于应用层协议。
JavaEdge
2023/02/26
1K0
如何设计可向后兼容的RPC协议
RPC接口简介「建议收藏」
RPC(Remote Procedure Call Protocol)远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。比较正式的描述是:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
全栈程序员站长
2022/11/08
3K0
Java微服务RPC选型Dubbo还是SpringCloud?
国内最早开源的RPC框架,由阿里巴巴公司开发并于2011年末对外开源,仅支持Java
JavaEdge
2021/02/22
3.6K0
为什么HTTP REST比RPC更受欢迎|微服务
问就是微服务,产品层面上,每个团队都可以单独完成服务的开发和部署,而无需与其他团队协调,以便产品可以在不同的时间和团队完成快速迭代。技术层面上,保证服务之间的隔离性,出现问题可以通过超时、熔断、限流、降级等技术保证服务之互不影响....诸多好处。
用户5166556
2023/03/18
4310
为什么HTTP REST比RPC更受欢迎|微服务
相关推荐
RPC框架:从原理到选型,一文带你搞懂RPC
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档