Hessian2比Java原生序列化快得多,因其采用紧凑二进制协议:字段名只传一次、基本类型直写、集合专用编码、跳过transient字段、不依赖Serializable接口,体积降至50%,反序列化耗时仅20%。

为什么 Hessian2 比 Java 原生序列化快得多
因为 Java 原生 Serializable 是反射驱动、带完整类元信息、无压缩的二进制格式,序列化后体积大、GC 压力高、反序列化要反复查类加载器。而 Hessian2 是紧凑二进制协议:字段名只传一次、基本类型直写、集合和 map 有专用编码、跳过 transient 字段、不依赖 Serializable 接口——这些让它序列化体积降到 Java 的 50%,反序列化耗时降到 20%。
在 Dubbo 3.2+ 中启用 Hessian2 的真实配置方式
Dubbo 3.2 起默认改用 fastjson2,但若你明确要切回 Hessian2(比如兼容老服务、避免 JSON 的字符串解析开销),必须显式指定,且注意版本兼容性:
-
dubbo.protocol.serialization必须设为hessian2,不能写成hessian(后者是已废弃的旧版) - Spring Boot 项目中,
application.yml配置示例:dubbo: protocol: serialization: hessian2 - Java Config 方式:
@Bean public ProtocolConfig protocolConfig() { ProtocolConfig config = new ProtocolConfig(); config.setSerialization("hessian2"); return config; } - 确保依赖中没有冲突的
hessian低版本 jar(如hessian-3.x),Dubbo 3.3+ 内置的是阿里魔改版hessian-lite,不走 Maven 中央仓的原始 hessian
Hessian2 在 Dubbo 3.3+ 中的 ImmutableMap 性能陷阱与绕过方法
如果你的服务 DTO 里用了 ImmutableMap(比如 Guava 或 JDK 14+ 的 Map.of()),默认 Hessian2 会退化为慢路径反射遍历,实测性能下降 40%。Dubbo 3.3 引入了开关来优化它:
- 添加 JVM 参数或配置项:
dubbo.protocol.hessian2.optimize-immutable-map=true - 该开关仅在 Dubbo ≥ 3.3.0 有效,3.2.x 即使加了也无效
- 开启后,Hessian2 会识别
ImmutableMap的内部结构,跳过反射,直接读取其私有字段entryArray和size - 注意:该优化对
ImmutableList/ImmutableSet同样生效,但不覆盖自定义不可变容器
什么时候不该强行用 Hessian2
它不是万能加速器,几个关键限制必须提前看清:
- 跨语言能力弱:
Hessian2虽标称跨语言,但实际只有 Java 客户端成熟;Go/Python 的 Hessian 实现要么不维护,要么不兼容 Dubbo 的魔改字段编码 - 调试困难:二进制流无法直接阅读,出问题时抓包看到的是乱码,不如
json或protobuf可读 - 泛型擦除导致反序列化失败:比如
List<User>反序列化后变成List<Object>,需配合Hessian2的type属性或手动注册泛型解析器 - 不支持
LocalDateTime等新时间类型(除非升级到 Dubbo 3.2.14+ 并启用hessian2.java8.time.support=true)
真正影响性能的往往不是序列化本身,而是你是否让 Hessian2 在它擅长的场景里工作——纯 Java 内部服务调用、DTO 字段稳定、不依赖泛型运行时信息。一旦跨语言或需强 schema 演进,就该换 protobuf 或 triple 协议了。

















