Dubbo 序列化协议相关面试问题¶
一、为什么需要序列化¶
跨 JVM 调用对象,必须把对象转成字节流在网络上传,对端再还原。RPC 框架必须选一种序列化协议。
二、常见序列化协议¶
| 协议 | 特点 | 性能 |
|---|---|---|
| Hessian2 | Dubbo 默认,跨语言,自描述 | 中等 |
| JSON | 可读性好,体积大 | 慢 |
| Java 原生序列化 | JDK 自带,丑且慢 | 差 |
| Kryo | 高性能,只支持 Java | 快 |
| Protostuff | 基于 Protobuf,快 | 快 |
| Protobuf | 跨语言,需要 .proto 文件 | 很快 |
| Fury | 阿里开源,新一代 | 极快 |
三、Hessian2 为什么是默认¶
- 跨语言(Java、Python、PHP)。
- 自带类型描述,不需要 ID 映射。
- 比 Java 原生序列化快很多。
缺点:序列化流里带类名、字段名,体积比 Protobuf 大。
四、选择标准¶
- 性能优先:Kryo / Protostuff / Fury。
- 跨语言:Hessian2 / Protobuf。
- 调试友好:JSON。
五、序列化常见坑¶
1. 类必须实现 Serializable¶
虽然 Hessian2 不强制,但 Dubbo 框架层面建议实现。
2. 版本号 serialVersionUID¶
不统一可能反序列化失败。
3. 循环引用¶
Hessian2 支持循环引用,但 Kryo 默认不支持,要开 setReferences(true)。
4. 抽象类 / 接口字段¶
序列化时只写具体类型,反序列化时要能找到类。
5. 跨集群协议一致¶
提供者用 Hessian2,消费者用 Kryo,直接报错。
六、配置¶
或全局:
高频追问
- 为什么 Java 原生序列化慢?它序列化整个对象图 + 类描述 + 版本号。
- Protobuf 为什么快?用 varint、字段号代替字段名,二进制紧凑。