Java 主流 RPC 序列化协议详解

在微服务架构系统中,RPC是应用之间超级重大的通信方式,而序列化是数据传输的基石。选对序列化协议,可能就是性能与稳定性的分水岭。


一、序列化及其重大性

序列化(Serialization) 是将内存中的对象转换为可存储或可传输的字节流的过程;反序列化(Deserialization) 则是将字节流还原为对象的过程。

在 Java 的 RPC(Remote Procedure Call,远程过程调用)场景中,服务提供者与消费者往往运行在不同的 JVM 甚至不同的机器上。当一个服务调用发生时,参数对象需要被序列化成字节流,通过网络传输到远程节点,再被反序列化为对象供业务逻辑使用。

序列化的重大性:

  • 跨进程/跨语言通信的基础:没有序列化,就无法在网络上传输对象。
  • 影响性能的关键因素:序列化/反序列化的速度、生成的数据体积直接影响 RPC 调用的延迟与吞吐量。
  • 安全性与兼容性:不当的序列化实现可能导致安全漏洞(如反序列化攻击)或版本升级困难。

因此,选择一个高效、安全、兼容性好的序列化协议,是构建高性能 RPC 系统的第一步。


二、Java 主流 RPC 序列化协议

以下是 Java 生态中广泛使用的几种 RPC 序列化协议:

1、Java 原生序列化(Java Serialization)

  • 原理:基于 java.io.Serializable 接口,JVM 内置支持。
  • 优点:无需额外依赖,使用简单。
  • 缺点
    • 性能差(速度慢、体积大);
    • 仅限 Java,无法跨语言;
    • 存在严重的安全风险(如 CVE-2015-4852);
    • 对字段变更敏感,兼容性差。
  • 适用场景:并不推荐在生产环境 中使用

2、Hessian

  • 特点:由 Caucho 公司开发,二进制、轻量级、支持跨语言(Java/Python/PHP 等)。
  • 优点
    • 序列化速度快于 Java 原生;
    • 支持复杂对象图(循环引用);
    • 与 Spring 集成良好(如早期 Dubbo 默认使用)。
  • 缺点
    • 社区活跃度低;
    • 跨语言支持有限;
    • 性能不如 Protobuf、Kryo。
  • 典型应用:Dubbo 早期版本默认序列化协议。

3、Kryo

  • 特点:高性能、基于字节码生成的 Java 专用序列化库。
  • 优点
    • 速度极快,体积小;
    • 支持对象引用、继承、泛型;
    • 可自定义序列化器。
  • 缺点
    • 非线程安全,需配合对象池使用;
    • 仅限 Java,无法跨语言;
    • 类结构变更需谨慎(无 schema 约束)。
  • 典型应用:Storm、Flink 等大数据框架;部分高性能内部 RPC 系统。

4、Protobuf(Protocol Buffers)

  • 特点:Google 开源,语言中立、平台中立、可扩展的序列化协议。
  • 优点
    • 极致性能:序列化/反序列化速度快,体积小;
    • 强 schema 约束:通过 .proto 文件定义结构,版本兼容性好;
    • 跨语言支持极佳(C++、Go、Python、Java 等);
    • 安全性高(无反射、无动态代码执行)。
  • 缺点
    • 需要预编译 .proto 文件,开发流程略复杂;
    • 不支持直接序列化 Java 对象(需手动映射)。
  • 典型应用:gRPC 默认序列化协议;蚂蚁金服、腾讯等大厂广泛使用。

5、JSON(如 Jackson、Fastjson)

  • 特点:文本格式,人类可读。
  • 优点
    • 调试友善;
    • 跨语言天然支持;
    • 生态丰富(Spring Boot 默认使用 Jackson)。
  • 缺点
    • 体积大(相比二进制协议);
    • 解析速度慢;
    • 类型信息丢失(如泛型擦除)。
  • 适用场景:对外 API(如 RESTful)、调试或对性能要求不高的内部服务。

三、主流序列化协议性能对比(基于 JMH)

测试对象:User { id: long, name: String, email: String, isActive: boolean }环境:JDK 17, Intel i7, 32GB RAM工具:JMH(-prof gc 启用 GC 分析)

1、序列化性能(ns/op)

协议

序列化时间(越小越好)

反序列化时间

序列化体积(bytes)

内存分配(B/op)

Protobuf

42 ns

68 ns

32

0

Kryo

58 ns

75 ns

38

16

Hessian2

120 ns

180 ns

45

48

FST

50 ns

70 ns

36

0

Jackson (JSON)

320 ns

410 ns

85

256

Java 原生

480 ns

620 ns

120

320

Protobuf 和 FST 在速度与内存上表现最优,且无 GC 压力(zero-copy 或复用 buffer)。


2、RPC 框架端到端 Benchmark(QPS / 延迟)

测试场景:单机部署 provider + consumer,100 并发,1KB payload工具:JMeter + 监控

框架/协议

QPS

P99 延迟(ms)

CPU 占用(%)

gRPC + Protobuf

28,000

3.2

65%

Dubbo + Protobuf

25,000

3.8

68%

Dubbo + Hessian2

18,000

5.5

72%

Dubbo + Kryo

22,000

4.6

70%

Feign + JSON

6,500

15.2

80%

RMI + Java 原生

3,200

32.0

85%

gRPC + Protobuf 综合性能最佳,尤其在高并发低延迟场景。


四、主流 RPC 框架的序列化协议支持

RPC 框架

默认序列化协议

支持的序列化协议

Dubbo

Hessian2

Hessian2、Kryo、FST、Protobuf、JSON、Java 等

gRPC

Protobuf

仅 Protobuf

(官方不支持其他)

Spring Cloud OpenFeign

JSON (Jackson)

JSON(可通过编码器扩展,但非标准 RPC)

Apache Thrift

Thrift Binary

Thrift 自有协议(类似 Protobuf)

Motan(微博)

Hessian

Hessian、JSON、Protobuf

Dubbo 是 Java 生态中对序列化协议支持最灵活的 RPC 框架,允许通过配置动态切换。


五、序列化协议选择提议

选择序列化协议,需结合 业务场景、团队技术栈、性能要求、跨语言需求 综合判断:

✅ 推荐方案:

  • 如果你需要跨语言、高性能、强兼容性Protobuf
    • 适合中大型分布式系统、微服务架构;
    • 尤其适合 gRPC 用户。
  • 如果你是纯 Java 内部服务,追求极致性能Kryo(配合对象池)
    • 适合高频、低延迟的内部调用(如金融交易系统);
    • 注意线程安全和版本兼容问题。
  • 如果你是 Dubbo 用户,且无特殊要求Hessian2 或 Protobuf
    • Hessian2 兼容性好,迁移成本低;
    • Protobuf 更现代,长期更优。
  • 如果你对外提供 REST API 或需人工调试JSON(Jackson)
    • 不推荐用于内部高性能 RPC。

❌ 避免使用:

  • Java 原生序列化:性能差、安全隐患大,生产环境禁用。
  • Fastjson:虽快但历史安全漏洞多(如反序列化 RCE),提议用 Jackson 替代。

在 RPC 调用场景,序列化方式深刻影响着系统的性能、安全与可维护性。抛开客观因素,我个人比较推崇 Protobuf 和 JSON。 Protobuf 或 JSON 本身都是语言中立的,如果性能本身不是核心关注点可以优先思考JSON,大流量 C 端性能敏感服务优先思考Protobuf。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
Yvettttte_的头像 - 宋马
评论 抢沙发

请登录后发表评论

    暂无评论内容