Dubbo3 供给了 Triple(Dubbo3)、Dubbo2 协议,这是 Dubbo 结构的原生协议。除此之外,Dubbo3 也对很多第三方协议进行了集成,并将它们纳入 Dubbo 的编程与服务管理体系, 包含 gRPC、Thrift、JsonRPC、Hessian2、REST 等。以下要点介绍 Triple 与 Dubbo2 协议。

下一代 RPC 协议 – Triple

Triple 协议是 Dubbo3 推出的主力协议。Triple 意为第三代,经过 Dubbo1.0/ Dubbo2.0 两代协议的演进,以及云原生带来的技能规范化浪潮,Dubbo3 新协议 Triple 应运而生。

RPC 协议简介

协议是 RPC 的核心,它规范了数据在网络中的传输内容和格局。除有必要的请求、呼应数据外,一般还会包含额定操控数据,如单次请求的序列化方法、超时时刻、压缩方法和鉴权信息等。

协议的内容包含三部分:

  • 数据交换格局:界说 RPC 的请求和呼应目标在网络传输中的字节流内容,也叫作序列化方法;
  • 协议结构:界说包含字段列表和各字段语义以及不同字段的排列方法;
  • 协议经过界说规矩、格局和语义来约好数据怎么在网络间传输。一次成功的 RPC 需求通信的两端都能够依照协议约好进行网络字节流的读写和目标转换。假如两端对运用的协议不能到达一致,就会呈现鸡同鸭讲,无法满意长途通信的需求。

Dubbo3 Triple 协议简介与选型思考

RPC 协议的规划需求考虑以下内容:

  • 通用性:一致的二进制格局,跨言语、跨渠道、多传输层协议支撑
  • 扩展性:协议增加字段、晋级、支撑用户扩展和附加事务元数据
  • 功用:As fast as it can be
  • 穿透性:能够被各种终端设备辨认和转发:网关、代理服务器等 通用性和高功用一般无法一起到达,需求协议规划者进行一定的取舍

HTTP/1.1

比于直接构建于 TCP 传输层的私有 RPC 协议,构建于 HTTP 之上的长途调用处理方案会有更好的通用性,如WebServices 或 REST 架构,运用 HTTP + JSON 能够说是一个事实规范的处理方案。

挑选构建在 HTTP 之上,有两个最大的优势:

  • HTTP 的语义和可扩展功用很好的满意 RPC 调用需求。
  • 通用性,HTTP 协议简直被网络上的一切设备所支撑,具有很好的协议穿透性。

但也存在比较显着的问题:

  • 典型的 Request – Response 模型,一个链路上一次只能有一个等待的 Request 请求。会产生 HOL。
  • Human Readable Headers,运用更通用、更易于人类阅览的头部传输格局,但功用相当差
  • 无直接 Server Push 支撑,需求运用 Polling Long-Polling 等变通形式

gRPC

上面说到了在 HTTP 及 TCP 协议之上构建 RPC 协议各自的优缺点,相比于 Dubbo 构建于 TCP 传输层之上,Google 挑选将 gRPC 直接界说在 HTTP/2 协议之上。gRPC 的优势由 HTTP2 和 Protobuf 承继而来。

  • 根据 HTTP2 的协议满足简略,用户学习本钱低,天然有 server push / 多路复用 / 流量操控才能
  • 根据 Protobuf 的多言语跨渠道二进制兼容才能,供给强大的一致跨言语才能
  • 根据协议自身的生态比较丰厚,K8s / etcd 等组件的天然支撑协议,云原生的事实协议规范

可是也存在部分问题

  • 对服务管理的支撑比较根底,更倾向于根底的 RPC 功用,协议层缺少必要的一致界说,关于用户而言直接用起来并不容易。
  • 强绑定 protobuf 的序列化方法,需求较高的学习本钱和改造本钱,关于现有的偏单言语的用户而言,搬迁本钱不可忽视

Triple 选型的考虑

最终咱们挑选了兼容 gRPC ,以 HTTP2 作为传输层构建新的协议,也就是 Triple。容器化使用程序和微服务的兴起促进了针对负载内容优化技能的发展。客户端中运用的传统通信协议( RESTFUL或其他根据 HTTP 的自界说协议)难以满意使用在功用、可维护性、扩展性、安全性等便利的需求。一个跨言语、模块化的协议会逐渐成为新的使用开发协议规范。自从 2017 年 gRPC 协议成为 CNCF 的项目后,包含 K8s、etcd 等越来越多的根底设备和事务都开始运用 gRPC 的生态,作为云原生的微服务化结构, Dubbo 的新协议也完美兼容了 gRPC。而且,关于 gRPC 协议中一些不完善的部分, Triple 也将进行增强和补充。那么,Triple 协议是否处理了上面咱们说到的一系列问题呢?

  • 功用上: Triple 协议采取了 metadata 和 payload 分离的策略,这样就能够避免中间设备,如网关进行 payload 的解析和反序列化,从而下降呼应时刻。
  • 路由支撑上,由于 metadata 支撑用户增加自界说 header ,用户能够根据 header 更便利的划分集群或者进行路由,这样发布的时分切流灰度或容灾都有了更高的灵敏性。
  • 安全性上,支撑双向 TLS 认证(mTLS)等加密传输才能。
  • 易用性上,Triple 除了支撑原生 gRPC 所推荐的 Protobuf 序列化外,运用通用的方法支撑了 Hessian / JSON 等其他序列化,能让用户更便利的晋级到 Triple 协议。对原有的 Dubbo 服务而言,修正或增加 Triple 协议 只需求在声明服务的代码块增加一行协议装备即可,改造本钱简直为 0。

Dubbo3 Triple 协议简介与选型思考

现状

1、完整兼容 gRPC、客户端/服务端能够与原生 gRPC 客户端打通

2、现在现已经过大规模出产实践验证,到达出产等级

特点与优势

1、具有跨言语互通的才能,传统的多言语多 SDK 形式和 Mesh 化跨言语形式都需求一种更通用易扩展的数据传输格局。

2、供给更完善的请求模型,除了 Request/Response 模型,还应该支撑 Streaming 和 Bidirectional。

3、易扩展、穿透性高,包含但不限于 Tracing / Monitoring 等支撑,也应该能被各层设备辨认,网关设备等能够辨认数据报文,对 Service Mesh 布置友爱,下降用户了解难度。

4、多种序列化方法支撑、滑润晋级。

5、支撑 Java 用户无感知晋级,不需求界说繁琐的 IDL 文件,仅需求简略的修正协议名便能够轻松晋级到 Triple 协议。

Triple 协议简介

根据 gRPC 协议进行进一步扩展

  • Service-Version → “tri-service-version” {Dubbo service version}
  • Service-Group → “tri-service-group” {Dubbo service group}
  • Tracing-ID → “tri-trace-traceid” {tracing id}
  • Tracing-RPC-ID → “tri-trace-rpcid” {_span id _}
  • Cluster-Info → “tri-unit-info” {cluster infomation}

其间 Service-Version 跟 Service-Group 别离标识了 Dubbo 服务的 version 跟 group 信息,由于 grpc 的 path 申明晰 service name 跟 method name,相比于 Dubbo 协议,缺少了 version 跟 group 信息;Tracing-ID、Tracing-RPC-ID 用于全链路追踪才能,别离表明 tracing id 跟 span id 信息;Cluster-Info 表明集群信息,能够运用其构建一些如集群划分等路由相关的灵敏的服务管理才能。

Triple Streaming

Triple 协议相比传统的 unary 方法,多了现在供给的 Streaming RPC 的才能

  • Streaming 用于什么场景呢?

在一些大文件传输、直播等使用场景中, consumer 或 provider 需求跟对端进行很多数据的传输,由于这些情况下的数据量是非常大的,因而是没有办法能够在一个 RPC 的数据包中进行传输,因而关于这些数据包咱们需求对数据包进行分片之后,经过屡次 RPC 调用进行传输,假如咱们对这些现已拆分了的 RPC 数据包进行并行传输,那么到对端后相关的数据包是无序的,需求对接收到的数据进行排序拼接,相关的逻辑会非常复杂。但假如咱们对拆分了的 RPC 数据包进行串行传输,那么对应的网络传输 RTT 与数据处理的时延会是非常大的。

为了处理以上的问题,而且为了很多数据的传输以流水线方法在 consumer 与 provider 之间传输,因而 Streaming RPC 的模型应运而生。

经过 Triple 协议的 Streaming RPC 方法,会在 consumer 跟 provider 之间树立多条用户态的长衔接,Stream。同一个 TCP 衔接之上能一起存在多个 Stream,其间每条 Stream 都有 StreamId 进行标识,关于一条 Stream 上的数据包会以顺序方法读写。

总结

在 API 范畴,最重要的趋势是规范化技能的兴起。Triple 协议是 Dubbo3 推出的主力协议。它采用分层规划,其数据交换格局根据 Protobuf (Protocol Buffers) 协议开发,具有优异的序列化/反序列化功率,当然还支撑多种序列化方法,也支撑很多开发言语。在传输层协议,Triple 挑选了 HTTP/2,相较于 HTTP/1.1,其传输功率有了很大提升。此外 HTTP/2 作为一个成熟的开放规范,具有丰厚的安全、流控等才能,一起具有良好的互操作性。Triple 不仅能够用于 Server 端服务调用,也能够支撑浏览器、移动 App 和 IoT 设备与后端服务的交互,一起 Triple协议无缝支撑 Dubbo3 的全部服务管理才能。

在 Cloud Native 的潮流下,跨渠道、跨厂商、跨环境的体系间互操作性的需求必然会催生根据开放规范的 RPC 技能,而 gRPC 顺应了历史趋势,得到了越来越广泛地使用。在微服务范畴,Triple 协议的提出与落地,是 Dubbo3 迈向云原生微服务的一大步。

附录:Dubbo2 Protocol SPEC

ProtocolSPEC!

Dubbo3 Triple 协议简介与选型思考

  • Magic – Magic High & Magic Low (16 bits)Identifies dubbo protocol with value: 0xdabb
  • Req/Res (1 bit)Identifies this is a request or response. Request – 1; Response – 0.
  • 2 Way (1 bit)Only useful when Req/Res is 1 (Request), expect for a return value from server or not. Set to 1 if need a return value from server.
  • Event (1 bit)Identifies an event message or not, for example, heartbeat event. Set to 1 if this is an event.
  • Serialization ID (5 bit)Identifies serialization type: the value for fastjson is 6.
  • Status (8 bits)Only useful when Req/Res is 0 (Response), identifies the status of response
    • 20 – OK
    • 30 – CLIENT_TIMEOUT
    • 31 – SERVER_TIMEOUT
    • 40 – BAD_REQUEST
    • 50 – BAD_RESPONSE
    • 60 – SERVICE_NOT_FOUND
    • 70 – SERVICE_ERROR
    • 80 – SERVER_ERROR
    • 90 – CLIENT_ERROR
    • 100 – SERVER_THREADPOOL_EXHAUSTED_ERROR
  • Request ID (64 bits)Identifies an unique request. Numeric (long).
  • Data Length (32)Length of the content (the variable part) after serialization, counted by bytes. Numeric (integer).
  • Variable PartEach part is a byte[] after serialization with specific serialization type, identifies by Serialization ID.

Every part is a byte[] after serialization with specific serialization type, identifies by Serialization ID

  1. If the content is a Request (Req/Res = 1), each part consists of the content, in turn is:
    • Dubbo version
    • Service name
    • Service version
    • Method name
    • Method parameter types
    • Method arguments
    • Attachments
  1. If the content is a Response (Req/Res = 0), each part consists of the content, in turn is:
    • Return value type, identifies what kind of value returns from server side: RESPONSE_NULL_VALUE – 2, RESPONSE_VALUE – 1, RESPONSE_WITH_EXCEPTION – 0.
    • Return value, the real value returns from server.

注意:关于 (Variable Part) 变长部分,当时版本的 dubbo 结构运用 json 序列化时,在每部分内容间额定增加了换行符作为分隔,请选手在 Variable Part 的每个 part 后额定增加换行符, 如:

Dubbo version bytes (换行符)
Service name bytes  (换行符)
...