Dubbo 支持哪些调用协议?


一则或许对你有用的小广告

欢迎加入小哈的星球,你将获得:专属的实战项目(4个项目都能学) / 1v1 提问 / 简历修改 / Java 学习路线 / 社群讨论 / 学习打卡 / 每月赠书

  • 《Spring AI 项目实战(问答机器人、RAG 智能客服、联网搜索)》已完结,基于 Spring AI + Spring Boot 3.x + JDK 21...查看介绍

  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...查看介绍;演示链接:http://116.62.199.48:7070/

  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接:http://116.62.199.48/

  • 新开坑项目:《从零手撸:秒杀系统高并发优化实战》 正在更新中...,查看介绍

截止目前,星球内专栏累计输出 150w+ 字,讲解图 5110+ 张,还在持续爆肝中.. 后续还会上新更多项目,已有 4700+ 小伙伴加入学习,欢迎点击围观

面试考察点

  1. 基础掌握度:面试官不仅仅是想知道你背了几个协议名字,更是想看你能不能说清楚每种协议的特点、适用场景,以及在生产环境中是怎么选型的。能说出 "dubbo 协议适合小数据量高并发" 和 "triple 协议支持跨语言" 这种差异化认知,才是面试官想听的。

  2. 架构理解深度:协议本质上决定了 RPC 框架的通信模型和性能上限。理解不同协议的底层传输方式(TCP、HTTP)、序列化机制(Hessian2、Protobuf),说明你不只是 API 调用者,而是理解 Dubbo 的通信骨架。

  3. 版本演进意识:Dubbo 3.x 推出了 Triple 协议作为新的默认推荐,基于 gRPC 和 HTTP/2。知道这个演进趋势,说明你关注社区动态,不是还停留在 Dubbo 2.x 的认知里。

核心答案

Dubbo 主要支持以下几种调用协议:

协议 底层传输 默认序列化 默认端口 适用场景 推荐指数
dubbo TCP 长连接 Hessian2 20880 高并发小数据量 ⭐⭐⭐
triple HTTP/2 Protobuf 50051 跨语言、Mesh、网关 3.x 推荐
rest HTTP 短连接 JSON 8080 对外开放 API ⭐⭐
hessian HTTP 短连接 Hessian 8080 与 Hessian 服务互通
thrift TCP 长连接 Thrift 40880 高性能跨语言 ⭐⭐
grpc HTTP/2 Protobuf 50051 gRPC 生态互通 ⭐⭐
webservice HTTP 短连接 SOAP XML 8080 遗留系统集成

一句话结论:Dubbo 2.x 时代 dubbo 协议是默认,Dubbo 3.x 时代 triple 协议成为官方推荐。新项目直接上 Triple,老项目平滑迁移。

深度解析

一、dubbo 协议——经典之选

dubbo 协议是 Dubbo 框架的原创协议,也是 2.x 版本的默认协议,用的最多最成熟。

Dubbo 协议报文结构
Dubbo 协议报文结构

上图是 dubbo 协议的报文结构,总共 16 字节的固定头部 + 可变数据体。关键设计点:

  • Magic Number(魔数)0xdabb,用于快速识别是否为 dubbo 协议的报文,类似 "暗号"
  • 标志位:标记请求/响应方向、序列化方式(Hessian2、FastJson、Kryo 等)、是否单向调用等
  • 消息 ID:用于将请求和响应做匹配,因为底层 TCP 是长连接,可能同时存在多个未完成的请求
  • 数据长度:标识 body 的字节长度,接收方据此判断报文是否完整

dubbo 协议的核心特点:

  • 单一长连接 + NIO 非阻塞:消费者和服务提供者之间维持一条 TCP 长连接,所有请求复用这条连接,通过 NIO 实现非阻塞通信
  • 默认 Hessian2 序列化:Hessian2 是一种二进制序列化方案,比 JSON 紧凑,性能也不错
  • 适合小数据量高并发:因为单连接复用,如果传大文件会把通道堵死,所以官方建议传输数据控制在 100KB 以内

配置示例:

<!-- 使用 dubbo 协议 -->
<dubbo:protocol name="dubbo" port="20880" />

<!-- 配置参数优化 -->
<dubbo:protocol name="dubbo" port="20880"
    threads="200"          <!-- 服务端线程池大小 -->
    iothreads="4"          <!-- IO 线程数 -->
    accepts="1000"         <!-- 最大连接数 -->
    serialization="hessian2" />

需要注意的坑dubbo 协议是单连接模型,如果消费者端并发量特别大,可能会成为瓶颈。可以通过配置多个连接(connections 参数)来缓解,但本质上还是不如多路复用来得优雅。

二、triple 协议——新一代首选

Triple 协议是 Dubbo 3.x 的重点,也是官方主推的新一代协议。它基于 HTTP/2 构建,兼容 gRPC 协议。

Triple 协议架构图
Triple 协议架构图

Triple 协议的架构如图所示。核心就是基于 HTTP/2 的多路复用能力,在一个 TCP 连接上可以同时跑多个请求/响应流,互不阻塞。它同时兼容 gRPC 协议,这意味着 gRPC 生态的客户端可以直接调用 Dubbo 服务。详细来说:

  • HTTP/2 多路复用:解决了 dubbo 协议单连接的瓶颈问题,一条 TCP 连接上可以并发传输多个请求和响应
  • 兼容 gRPC:Triple 协议可以和 gRPC 客户端/服务端互调,打通了跨语言生态
  • 支持 Streaming:支持 Unary、Server Stream、Client Stream、Bidirectional Stream 四种调用模式
  • 更友好的网关穿透:因为基于 HTTP/2,天然支持 API Gateway、Service Mesh 等基础设施

配置示例:

<!-- Dubbo 3.x 使用 Triple 协议 -->
<dubbo:protocol name="triple" port="50051" />
// 使用注解方式配置 Triple 协议
@DubboService(protocol = "triple")
public class UserServiceImpl implements UserService {
    // ...
}

为什么 Triple 取代 dubbo 成为推荐? 说白了就是三点:跨语言互通、Mesh 友好、Streaming 支持。云原生时代,服务网格(Service Mesh)和 API 网关基本都基于 HTTP 协议,dubbo 协议这种私有 TCP 协议在这种架构下很不讨喜。

三、其他协议一览

REST 协议

基于标准的 HTTP REST 风格,使用 JSON 序列化。适合给前端、移动端或者第三方调用:

<dubbo:protocol name="rest" port="8080" />

说实话,如果你只是想暴露 REST API,直接用 Spring MVC 可能更主流。Dubbo REST 协议更多用在 "既要 RPC 内部调用,又要对外暴露 HTTP 接口" 的场景。

Thrift 协议

集成 Apache Thrift,适合需要跨语言调用的场景(比如 Java 和 Python、C++ 互通):

<dubbo:protocol name="thrift" port="40880" />

Thrift 性能很好,但 IDL 定义比较繁琐,而且社区活跃度不如 gRPC。

gRPC 协议

Dubbo 3.x 对 gRPC 的支持更加完善,可以直接使用 gRPC 的 IDL 定义服务:

<dubbo:protocol name="grpc" port="50051" />

不过 Triple 协议本身已经兼容 gRPC 了,所以在新项目中,一般不需要单独使用 grpc 协议,直接用 Triple 就行。

四、协议选型对比

Dubbo 协议选型决策图
Dubbo 协议选型决策图

选型决策如图所示,简化成一句话:

  • Dubbo 3.x 新项目:无脑上 Triple,一统江湖
  • Dubbo 2.x 老项目:继续用 dubbo 协议,有跨语言需求再考虑迁移到 Triple
  • 对外 API:REST 协议或者另起一个 Spring MVC 网关层

面试高频追问

  1. 追问:dubbo 协议为什么不适合传大数据?

    因为 dubbo 协议默认使用单一长连接,大数据包会长时间占用连接通道,导致其他请求排队等待。官方建议传输数据在 100KB 以内,超过的话可以考虑用 triple 协议或者把大文件拆分。

  2. 追问:Triple 协议和 gRPC 是什么关系?

    Triple 是基于 HTTP/2 构建的,向下兼容 gRPC 协议。可以理解为 Triple = gRPC 的超集,在 gRPC 的基础上增加了 Dubbo 的服务治理能力(路由、熔断、限流等)。所以 gRPC 客户端可以直接调用 Triple 协议的 Dubbo 服务。

  3. 追问:Dubbo 协议默认用什么序列化?能换吗?

    默认 Hessian2,可以通过 serialization 参数切换为 fastjsonkryofstprotostuff 等。Kryo 和 FST 性能更好但只支持 Java,跨语言场景用 Protobuf。

  4. 追问:一个服务能同时配多个协议吗?

    可以。一个服务可以同时暴露多个协议端口,比如同时配 dubbotriple,让不同类型的消费者用不同协议访问:

    <dubbo:protocol name="dubbo" port="20880" />
    <dubbo:protocol name="triple" port="50051" />
    
    <dubbo:service interface="com.example.UserService"
        protocol="dubbo,triple" />
    

常见面试变体

  • "Dubbo 默认用的是什么协议?为什么?"
  • "Triple 协议和 dubbo 协议的区别是什么?"
  • "Dubbo 如何实现跨语言调用?"
  • "Dubbo 的序列化方式有哪些?怎么选?"

记忆口诀

协议选型:Dubbo 三代看演进——2.x 用 dubbo(TCP 长连接、Hessian2),3.x 推 triple(HTTP/2、Protobuf、兼容 gRPC),对外用 REST。

一句话记忆dubbo 是自家私房菜,triple 是公开放标准。

总结

Dubbo 支持多种协议,核心就记住两个:dubbo 协议是 2.x 时代的经典,基于 TCP 长连接 + Hessian2 序列化,适合纯 Java 内部高并发调用;triple 协议是 3.x 时代的未来,基于 HTTP/2 兼容 gRPC,跨语言、Mesh 友好、支持 Streaming。面试时把这两个说清楚,再提一句其他协议的存在和适用场景,基本就够了。