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+ 小伙伴加入学习,欢迎点击围观
面试考察点
-
基础掌握度:面试官不仅仅是想知道你背了几个协议名字,更是想看你能不能说清楚每种协议的特点、适用场景,以及在生产环境中是怎么选型的。能说出 "dubbo 协议适合小数据量高并发" 和 "triple 协议支持跨语言" 这种差异化认知,才是面试官想听的。
-
架构理解深度:协议本质上决定了 RPC 框架的通信模型和性能上限。理解不同协议的底层传输方式(TCP、HTTP)、序列化机制(Hessian2、Protobuf),说明你不只是 API 调用者,而是理解 Dubbo 的通信骨架。
-
版本演进意识: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 协议的报文结构,总共 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 协议的架构如图所示。核心就是基于 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 3.x 新项目:无脑上 Triple,一统江湖
- Dubbo 2.x 老项目:继续用
dubbo协议,有跨语言需求再考虑迁移到 Triple - 对外 API:REST 协议或者另起一个 Spring MVC 网关层
面试高频追问
-
追问:dubbo 协议为什么不适合传大数据?
因为
dubbo协议默认使用单一长连接,大数据包会长时间占用连接通道,导致其他请求排队等待。官方建议传输数据在 100KB 以内,超过的话可以考虑用triple协议或者把大文件拆分。 -
追问:Triple 协议和 gRPC 是什么关系?
Triple 是基于 HTTP/2 构建的,向下兼容 gRPC 协议。可以理解为 Triple = gRPC 的超集,在 gRPC 的基础上增加了 Dubbo 的服务治理能力(路由、熔断、限流等)。所以 gRPC 客户端可以直接调用 Triple 协议的 Dubbo 服务。
-
追问:Dubbo 协议默认用什么序列化?能换吗?
默认 Hessian2,可以通过
serialization参数切换为fastjson、kryo、fst、protostuff等。Kryo 和 FST 性能更好但只支持 Java,跨语言场景用 Protobuf。 -
追问:一个服务能同时配多个协议吗?
可以。一个服务可以同时暴露多个协议端口,比如同时配
dubbo和triple,让不同类型的消费者用不同协议访问:<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。面试时把这两个说清楚,再提一句其他协议的存在和适用场景,基本就够了。
