共计 5506 个字符,预计需要花费 14 分钟才能阅读完成。
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 须要通信的两端都可能依照协定约定进行网络字节流的读写和对象转换。如果两端对应用的协定不能达成统一,就会呈现鸡同鸭讲,无奈满足近程通信的需要。
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。
现状
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
Protocol SPEC!
- 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
- 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
- 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 (换行符)
...