跳转至

Dubbo 序列化协议相关面试问题

一、为什么需要序列化

跨 JVM 调用对象,必须把对象转成字节流在网络上传,对端再还原。RPC 框架必须选一种序列化协议。

二、常见序列化协议

协议 特点 性能
Hessian2 Dubbo 默认,跨语言,自描述 中等
JSON 可读性好,体积大
Java 原生序列化 JDK 自带,丑且慢
Kryo 高性能,只支持 Java
Protostuff 基于 Protobuf,快
Protobuf 跨语言,需要 .proto 文件 很快
Fury 阿里开源,新一代 极快

三、Hessian2 为什么是默认

  • 跨语言(Java、Python、PHP)。
  • 自带类型描述,不需要 ID 映射。
  • 比 Java 原生序列化快很多。

缺点:序列化流里带类名、字段名,体积比 Protobuf 大。

四、选择标准

  1. 性能优先:Kryo / Protostuff / Fury。
  2. 跨语言:Hessian2 / Protobuf。
  3. 调试友好:JSON。

五、序列化常见坑

1. 类必须实现 Serializable

虽然 Hessian2 不强制,但 Dubbo 框架层面建议实现。

2. 版本号 serialVersionUID

不统一可能反序列化失败。

3. 循环引用

Hessian2 支持循环引用,但 Kryo 默认不支持,要开 setReferences(true)

4. 抽象类 / 接口字段

序列化时只写具体类型,反序列化时要能找到类。

5. 跨集群协议一致

提供者用 Hessian2,消费者用 Kryo,直接报错。

六、配置

@Service(serialization = "kryo")
public class UserServiceImpl implements UserService { ... }

或全局:

dubbo.protocol.serialization=kryo

高频追问

  • 为什么 Java 原生序列化慢?它序列化整个对象图 + 类描述 + 版本号。
  • Protobuf 为什么快?用 varint、字段号代替字段名,二进制紧凑。