Dubbo 通信协议介绍

前言

学习资源

主流的协议

Dubbo 3 支持多种协议,核心的协议包括:Dubbo、Triple、gRPC、Hessian、REST 等。

各种协议的对比

协议类型协议名 / 标识传输层核心特性适用场景是否默认协议
Dubbo 协议dubboTCP 单一长连接、NIO 异步通信、高性能高并发小数据量场景(消费者数 >> 提供者)
Triple 协议triHTTP/2 兼容 gRPC 生态、支持流式通信、跨语言能力增强多语言交互、流式数据传输
gRPC 协议grpcHTTP/2Google 开源 RPC 框架、高性能跨语言通信跨语言高性能服务调用
REST 协议restHTTP 严格遵循 RESTful 规范、支持 JSON/XML 格式浏览器调用、跨平台集成
Hessian 协议hessianHTTP 表单序列化、短连接、传输效率优于 WebService 文件 / 视频等大数据传输
Thrift 协议thriftTCPApache 开源 RPC 框架、强类型接口定义多语言服务交互
RMI 协议rmiTCPJava 远程方法调用、基于 JRMP 协议仅限 Java 生态的远程调用
WebServicewebserviceHTTP 基于 SOAP 协议、XML 序列化传统企业系统集成
MQTT 协议mqttTCP 发布 / 订阅模式、低带宽占用物联网设备通信
Redis 协议redis文本协议基于 Redis 的轻量级通信缓存操作、简单消息队列
Memcached 协议memcached文本协议 / 二进制协议轻量级键值存储、高效缓存机制分布式缓存、加速数据访问

核心协议的介绍

  • Dubbo 协议

    • Dubbo 默认使用 Dubbo 协议,基于单一长连接(TCP)和 NIO 异步通信,并采用 Hessian2 作为序列化协议。Dubbo 协议适用于单次传输数据量较小(通常在 100KB 以内)但并发量极高的场景。
    • 为了支撑高并发,通常服务提供者只部署少量机器,而服务消费者可能有上百台,每天调用量可达数亿次。此时,采用长连接最为合适 — 服务提供者只需与每个服务消费者维持一个长连接,例如总共 100 个连接,然后通过 NIO 异步通信处理所有请求,能够有效支撑大规模并发。
    • 如果在高并发场景下使用短连接,那么上亿次请求都会触发频繁的 TCP 连接建立与释放,服务提供者难以承受这种开销。需要注意的是,由于 Dubbo 协议是单一长连接,如果单次传输的数据量过大,会占用连接时间,从而降低整体并发处理能力。因此,Dubbo 协议更适合传输小数据量、支持高并发访问的业务场景。
  • Triple 协议

    • 基于 HTTP/1、HTTP/2 的高性能通信协议,使用 Protobuf 传输数据,完全兼容 gRPC 协议;支持 Unary、Streming 等通信模式;支持发布 REST 风格的 HTTP 服务。
    • Protobuf(Protocol Buffers) 是由 Google 开发的一种轻量级、高效的数据交换格式,它被用于结构化数据的序列化、反序列化和传输。相比于 XML 和 JSON 等文本格式,Protobuf 具有更小的数据体积、更快的解析速度和更强的可扩展性。
  • REST 协议

    • REST 协议就是平时常说的 RESTful,本质上把它称为协议是不准确的,因为 RESTful 是基于 HTTP/1 协议的。
    • 使⽤ REST 协议这种⽅式可以让 Dubbo 服务直接通过 URL 进⾏访问,同时也可以更好地与 SpringCloud 技术栈进⾏整合。
  • Hessian 协议

    • Hessian 协议使用 Hessian 作为序列化方式,采用多个短连接的通信模式。它适用于服务提供者数量多于消费者数量的场景,并且支持传输较大数据量(比如文件传输)。
    • 由于短连接在高并发情况下会带来较高的连接建立与释放开销,因此 Hessian 协议在分布式 RPC 调用中使用较少,更多用于需要传输文件或大数据块的特定业务场景。
  • gRPC 协议

    • Dubbo 中的 gRPC 协议就是使用 gRPC 来替换 Dubbo 的 RPC 调⽤,本质上将它称为协议是不准确的,因为 gRPC 是 Google 开源的高性能、通用的 RPC 框架。
    • gRPC 基于 HTTP/2 协议,默认使用 Protobuf 作为序列化协议,支持多路复用长连接,在一条 TCP 连接上同时处理多个并发请求。本质上 Dubbo 对于 gRPC 协议的⽀持,就是在原有 gRPC 客户端代码上进行了封装。
    • gRPC 适用于跨语言、跨平台的分布式系统,能够满足低延迟、高吞吐的同时提供良好的流式传输能力(支持客户端流、服务端流和双向流)。gRPC 在大文件传输场景下需要额外优化(如分块传输、流式传输),否则会占用连接资源并影响并发性能。
    • 由于 HTTP/2 的多路复用机制,gRPC 在传输中可同时进行多个请求而不会互相阻塞,适合数据量中等、需要高性能通信的场景,例如微服务之间的交互、移动端与服务端通信、IoT 设备数据上报等。
  • RMI 协议

    • RMI 协议基于 Java RMI(远程方法调用)实现,采用 Java 对象序列化(二进制)进行数据传输。通信方式为多个短连接,适用于服务消费者与服务提供者数量相近的场景,并支持传输较大数据(比如文件传输)。
    • 由于 Java 对象序列化的性能相对较低,且短连接在高并发情况下会带来较高的连接建立与释放开销,该协议在分布式 RPC 中应用较少,通常仅用于特定的文件传输或 Java 生态内的兼容性需求。

gRPC 的开发流程

  • (1) 通过 Protobuf 的 IDL 定义通信数据及操作。
  • (2) 通过 Maven 的插件,根据不同的编程语言生成成对应的代码
  • (3) 服务端发布 RPC 服务
    • (3.1) ⼀元调⽤
    • (3.2) 服务端流式 RPC
    • (3.3) 客户端流式 RPC
    • (3.4) 双向流式 RPC
  • (4) 客户端进⾏ RPC 服务的调⽤
    • (4.1) 通过 Stub 代理进⾏远程 RPC 的调⽤

Triple 新协议

Triple 是 Dubbo 3 新设计的基于 HTTP/1、HTTP/2 的高性能 RPC 通信协议,使用 Protobuf 传输数据,完全兼容 gRPC 协议;支持 Request-Response、Streaming 流式等通信模型,可同时运行在 HTTP/1 和 HTTP/2 之上。在阿里巴巴,Triple 协议广泛用于跨环境、跨语言、跨生态互通,已有数十万容器生产级使用。

Triple 协议的设计

  • 传输层

    • Triple 协议的底层是基于 HTTP/2 协议实现网络通信,所有数据(包括请求元数据和业务数据)均通过 HTTP/2 二进制帧传输‌。
  • 序列化层

    • Dubbo 3 默认采用 Protobuf 作为序列化协议,将 Java 对象转换为二进制数据流‌。

Triple 协议的特性

  • 多语言友好,推荐配合 Protobuf 使用 Triple 协议,使用 IDL 定义服务,并使用 Protobuf 编码业务数据
  • 更容易适配网关、Mesh 架构,可以更好地支持异构语言通信,且更加适应云原生场景
  • 支持 Streaming 流式通信,包括 Request Stream、Response Stream、Bi-direction Stream
  • 采用分层设计,其数据交换格式基于 Protobuf 协议开发,具备优秀的序列化 / 反序列化效率,当然还支持多种序列化方式,也支持众多开发语言
  • 不仅可以用于 Server 端服务调用,也可以支持浏览器、移动 App 和 IoT 设备与后端服务的交互,同时 Triple 协议无缝支持 Dubbo 3 的全部服务治理能力

Triple 协议的序列化机制

  • Triple 协议的本质:

    • 传输层:HTTP/2
    • 编解码:
      • 默认支持 application/grpc+proto,完全兼容 gRPC 标准
      • 兼容 HTTP/JSON 调用(但严格来说,gRPC 标准并没有支持 application/grpc+json,而是 Dubbo 自行扩展了 JSON 兼容功能)
  • Triple 接口类型与序列化逻辑:

    • 如果是 .proto 生成的接口
      • 完全走 Protobuf 序列化
        • 客户端和服务端都用 .proto 定义的结构进行 Protobuf 编解码
        • 兼容标准 gRPC 协议
    • 如果是 Java 接口(非 .proto 生成)
      • HTTP/JSON 调用(如 curl + application/json):
        • 完全走 Hessian2Json 或 Jackson 等 JSON 序列化
        • 传输层是 HTTP/1.1
        • 不会经过 Protobuf 序列化
  • Triple 协议为什么这样设计:

    • Triple 协议本质上是 gRPC 兼容协议
    • gRPC 强制要求底层用 Protobuf 编解码
    • Dubbo 为兼容老用户,支持「Java 接口直发」
    • 如果是 HTTP/JSON 调用,仍保持兼容 JSON(非 Protobuf 序列化)
  • Triple 协议的序列化机制总结

调用方式序列化服务定义模式
gRPC 标准调用(HTTP/2 + application/grpc+proto直接走 Protobuf 序列化基于 .proto 文件定义服务
HTTP/JSON 调用(HTTP/1 + application/json直接走 Hessian2Json 或 Jackson 序列化(不经过 Protobuf 序列化)基于 Java 接口(纯 POJO 接口)定义服务

Triple 协议的两种调用方式

服务定义方式是否支持 HTTP + JSON 调用是否支持 gRPC 客户端(协议)调用是否支持跨编程语言调用
基于 .proto 文件的服务定义❌ 不支持 HTTP + JSON 调用✅ 支持 gRPC 客户端(协议)调用,由于必须用 Protobuf 二进制,通常用 gRPC 调用✅ 支持跨编程语言调用
基于 Java 接口的服务定义(纯 POJO 接口)✅ 支持 HTTP + JSON 调用,内部直接走 Hessian2Json 或 Jackson 序列化(不经过 Protobuf 序列化)❌ 不支持 gRPC 客户端(协议)调用,由于 gRPC 仅支持 Protobuf 模式(使用 .proto 文件定义服务),因此 Java 接口 + Triple 协议的模式无法与谷歌官方原生的 gRPC 协议互相调用❌ 不支持跨编程语言调用

Triple 协议与经典 Dubbo 协议的区别

特性 Triple(Dubbo 3)Dubbo 协议(Dubbo 2)
传输协议 HTTP/2 自定义 TCP 协议(单连接)
序列化协议 Protobuf / Hessian2 / JSONHessian2(默认)
多语言支持是,天然支持 gRPC 互通较差(主要 Java)
网关支持支持 Envoy、APISIX、Kong 不兼容
流式通信支持(Streaming RPC)不支持
扩展性兼容 gRPC 插件生态自定义扩展(Dubbo Filter)
可观测性标准化 Trace、Metrics 自行扩展
连接复用 HTTP/2 多路复用单连接单请求
协议标准化程度标准协议,开放生态私有协议

Dubbo 官方给出为什么选择 Triple 协议的原因

  • 容器化和微服务的兴起促进了针对负载内容优化技术的发展,客户端中使用的传统通信协议(RESTful 或其他基于 HTTP 的自定义协议)难以满足应用在性能、可维护性、扩展性、安全性等方便的需求。一个跨语言、模块化的协议会逐渐成为新的应用开发协议标准。
  • 自从 2017 年 gRPC 协议成为 CNCF 的项目后,包括 K8S、ETCD 等越来越多的基础设施和业务都开始使用 gRPC 的生态,作为云原生的微服务化框架,Dubbo 的新协议也完美兼容了 gRPC。并且,对于 gRPC 协议中一些不完善的部分,Triple 也将进行增强和补充。
  • Triple 协议的推出,旨在解决 Dubbo 2 中私有 Dubbo 协议带来的互通性问题。简而言之,Dubbo 协议虽然性能好,但是大家不认,带来的问题就是:
    • 跨语言限制:对于有多语言诉求的公司来说不够友好,需要额外的工作量。
    • 缺乏标准化:Dubbo 协议没有被广泛认可和标准化,无法享受到标准化协议的优势。
    • 穿透性差:网络环境中的防火墙、网关、代理服务器等不能识别 Dubbo 协议。

Dubbo 原本已经支持了 gRPC 协议,为什么还要自研 Triple 协议

  • 如果只支持 gRPC 协议,不能够体现 Dubbo 的价值,毕竟 gRPC 是 Google 开源的。
  • Triple 协议不绑定 IDL,支持使用 Java 接口定义服务。gRPC 需要使用 Protobuf,而 Triple 可以通过 Java 接口的方式进行服务暴露。
  • Triple 协议同时支持 HTTP/1 和 HTTP/2 协议,而 gRPC 只支持 HTTP/2 协议。

协议发展历程

  • Dubbo 支持多种协议,在 3.0 版本之前支持 Dubbo、gRPC、Hessian2、REST 等核心协议。
  • 从 Dubbo 3.0 开始,Dubbo 官方新引入了自研的 Triple 协议,不过也保留了 Dubbo 和 REST 协议的支持。
  • 从 Dubbo 3.2 开始,Dubbo 官方已经废弃原有的 gRPC 协议,使用 Triple 协议进行替代,Triple 协议完全兼容 gRPC 协议。
  • 从 Dubbo 3.3 开始,Dubbo 官方直接移除了 REST 协议的直接支持,使用 Triple 协议间接支持 REST 协议。

提示

  • 自 Dubbo 2.6.0 版本开始,Dubbo 合并了当当网捐献的 DubboX 4 中的主要特性,其中就包括了基于 RESTeasy 3.0.19.Final 的 REST 支持,具备 JAX-RS 2.0 规范中所有的能力。
  • 自 Dubbo 3.3 版本开始,原有的 REST 协议实现已被移除,由 Triple 协议提供更全面的 REST 支持。使用 Triple 协议发布 REST 风格的服务非常简单,通常只需要在服务接口上添加相应的注解,支持三种注解方式:内置注解、Spring Web 注解、JAX-RS 注解。

选择 RPC 协议

参考资料