核心概念

序列化是将对象转换为字节流的过程,反序列化是将字节流还原为对象。在 RPC 调用中,序列化的性能直接影响整体调用效率。

Dubbo 支持多种序列化方式,可以根据性能、兼容性、跨语言等需求灵活选择。

核心指标

  • 性能:序列化/反序列化速度
  • 体积:序列化后的数据大小
  • 兼容性:跨版本、跨语言支持
  • 易用性:是否需要额外配置

支持的序列化方式

1. hessian2(默认,推荐)

特点

  • Dubbo 的默认序列化方式
  • 二进制格式,性能好,体积小
  • 跨语言支持(Java、C++、Python、PHP)
  • 不需要额外依赖

配置方式

// 注解配置
@Service(serialization = "hessian2")
public class UserServiceImpl implements UserService {
    // ...
}

// YAML 配置
dubbo:
  protocol:
    name: dubbo
    serialization: hessian2

性能数据

序列化速度:⭐⭐⭐⭐
反序列化速度:⭐⭐⭐⭐
数据体积:⭐⭐⭐⭐
跨语言:⭐⭐⭐⭐

适用场景

  • ✅ 默认选择,兼顾性能和兼容性
  • ✅ 常规业务场景
  • ✅ 不需要极致性能优化的场景
  • ❌ 复杂对象图(循环引用)可能有问题

示例

// 实体类(无需特殊注解)
public class User implements Serializable {
    private Long id;
    private String name;
    private Integer age;
    // getter/setter
}

@Service(serialization = "hessian2")
public class UserServiceImpl implements UserService {
    @Override
    public User getUser(Long userId) {
        return userMapper.selectById(userId);
    }
}

2. kryo(高性能,推荐优化场景)

特点

  • 性能最优,速度最快
  • 数据体积最小
  • 需要提前注册类(否则性能下降)
  • 不支持跨语言

配置方式

<!-- 添加依赖 -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-serialization-kryo</artifactId>
</dependency>
// 注解配置
@Service(serialization = "kryo")
public class UserServiceImpl implements UserService {
    // ...
}

// 注册类(可选,但推荐)
public class KryoConfig {
    static {
        // 预先注册类,提升性能
        SerializationOptimizer optimizer = new SerializationOptimizer() {
            @Override
            public Collection<Class> getSerializableClasses() {
                return Arrays.asList(
                    User.class,
                    Order.class,
                    Product.class
                );
            }
        };
        // 设置优化器
        System.setProperty(
            "dubbo.application.serialization-optimizer",
            "com.example.KryoConfig"
        );
    }
}

性能数据

序列化速度:⭐⭐⭐⭐⭐
反序列化速度:⭐⭐⭐⭐⭐
数据体积:⭐⭐⭐⭐⭐
跨语言:❌

适用场景

  • ✅ 对性能要求极高的场景
  • ✅ 内部微服务调用(Java to Java)
  • ✅ 对象结构固定,可以预先注册
  • ❌ 跨语言调用
  • ❌ 频繁变更实体类的场景

性能对比

// 基准测试(相同对象)
Hessian2序列化 100ms体积 1000 字节
Kryo    序列化  50ms体积  600 字节
提升    速度快 2 体积减少 40%

3. protobuf(跨语言,高性能)

特点

  • Google 开源的序列化框架
  • 性能优秀,接近 Kryo
  • 跨语言支持最好(Java、Go、Python、C++等)
  • 需要定义 .proto 文件
  • 强类型,向后兼容性好

配置方式

<!-- 添加依赖 -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-serialization-protobuf</artifactId>
</dependency>
<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
</dependency>

定义 Proto 文件

// user.proto
syntax = "proto3";

package com.example;

message UserProto {
    int64 id = 1;
    string name = 2;
    int32 age = 3;
    string email = 4;
}

message GetUserRequest {
    int64 user_id = 1;
}

message GetUserResponse {
    UserProto user = 1;
}

生成 Java 类

protoc --java_out=./src/main/java user.proto

使用示例

@Service(serialization = "protobuf")
public class UserServiceImpl implements UserService {
    
    @Override
    public UserProto getUser(Long userId) {
        User user = userMapper.selectById(userId);
        // 转换为 Protobuf 对象
        return UserProto.newBuilder()
            .setId(user.getId())
            .setName(user.getName())
            .setAge(user.getAge())
            .setEmail(user.getEmail())
            .build();
    }
}

性能数据

序列化速度:⭐⭐⭐⭐⭐
反序列化速度:⭐⭐⭐⭐⭐
数据体积:⭐⭐⭐⭐⭐
跨语言:⭐⭐⭐⭐⭐

适用场景

  • ✅ 跨语言调用(Java、Go、Python 互调)
  • ✅ 对性能和体积要求高
  • ✅ 长期维护的项目(向后兼容性好)
  • ✅ 配合 triple 协议使用(兼容 gRPC)
  • ❌ 开发成本较高(需要维护 .proto 文件)

4. fastjson / jackson(JSON 系列)

特点

  • 文本格式,可读性好
  • 易于调试
  • 跨语言支持好
  • 性能较差,体积大

配置方式

<!-- FastJson -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-serialization-fastjson</artifactId>
</dependency>

<!-- Jackson -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-serialization-jackson</artifactId>
</dependency>
@Service(serialization = "fastjson")
public class UserServiceImpl implements UserService {
    // ...
}

性能数据

序列化速度:⭐⭐⭐
反序列化速度:⭐⭐
数据体积:⭐⭐(文本格式,体积大)
跨语言:⭐⭐⭐⭐

适用场景

  • ✅ 开发调试阶段(可以直接查看传输内容)
  • ✅ 对性能要求不高的场景
  • ✅ 需要与前端直接交互
  • ❌ 内部高性能调用(推荐二进制格式)

示例

// JSON 序列化后的数据(可读性好,但体积大)
{
    "id": 123456789,
    "name": "张三",
    "age": 25,
    "email": "zhangsan@example.com"
}

5. fst(快速序列化)

特点

  • Fast Serialization,Java 对象序列化
  • 性能接近 Kryo
  • 兼容 JDK 序列化

配置方式

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-serialization-fst</artifactId>
</dependency>
@Service(serialization = "fst")
public class UserServiceImpl implements UserService {
    // ...
}

适用场景

  • ✅ Java 内部调用
  • ✅ 替代 JDK 序列化
  • ❌ 跨语言场景

6. jdk(Java 原生序列化)

特点

  • Java 原生支持
  • 性能最差
  • 数据体积最大
  • 不推荐使用

配置方式

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

性能数据

序列化速度:⭐
反序列化速度:⭐
数据体积:⭐
跨语言:❌

适用场景

  • ❌ 不推荐使用(已过时)
  • ✅ 与遗留系统兼容

序列化方式对比

性能对比表

序列化方式 序列化速度 反序列化速度 体积 跨语言 推荐度
kryo ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
protobuf ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
hessian2 ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
fst ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
fastjson ⭐⭐⭐ ⭐⭐ ⭐⭐ ⭐⭐⭐⭐ ⭐⭐
jackson ⭐⭐⭐ ⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
jdk

实际测试数据(同一对象)

// 测试对象:User (id, name, age, email, createTime)

序列化时间10000):
- Kryo:      50ms
- Protobuf:  60ms
- Hessian2:  100ms
- FastJson:  200ms
- JDK:       500ms

序列化后体积
- Kryo:      45 字节
- Protobuf:  50 字节
- Hessian2:  80 字节
- FastJson:  120 字节
- JDK:       200 字节

选择建议

场景 1:常规业务(默认选择)

// 推荐:hessian2(默认)
@Service(serialization = "hessian2")
public class UserServiceImpl implements UserService {
    // 性能好,兼容性好,无需额外配置
}

场景 2:高性能要求(Java 内部调用)

// 推荐:kryo
@Service(serialization = "kryo")
public class OrderServiceImpl implements OrderService {
    // 性能最优,适合内部调用
}

// 注册类以提升性能
public class KryoOptimizer implements SerializationOptimizer {
    @Override
    public Collection<Class> getSerializableClasses() {
        return Arrays.asList(
            Order.class, OrderItem.class, User.class
        );
    }
}

场景 3:跨语言调用

// 推荐:protobuf + triple 协议
@Service(
    protocol = "triple",
    serialization = "protobuf"
)
public class UserServiceImpl implements UserService {
    // 支持 Java、Go、Python 等多语言调用
}

场景 4:开发调试

// 推荐:fastjson / jackson
@Service(serialization = "fastjson")
public class DebugServiceImpl implements DebugService {
    // JSON 格式,方便查看传输内容
}

场景 5:混合使用

# 不同服务使用不同序列化方式
dubbo:
  protocol:
    name: dubbo
    serialization: hessian2  # 默认序列化
// 服务级别覆盖
@Service(serialization = "kryo")  // 高性能服务
public class OrderServiceImpl { }

@Service(serialization = "protobuf")  // 跨语言服务
public class OpenApiServiceImpl { }

@Service(serialization = "hessian2")  // 常规服务
public class UserServiceImpl { }

最佳实践

1. 性能优化

// 1. 使用 Kryo 并注册类
@Bean
public SerializationOptimizer kryoOptimizer() {
    return () -> Arrays.asList(
        User.class, Order.class, Product.class
    );
}

// 2. 避免大对象传输
// 不推荐:传输整个列表
List<Order> getOrders(Long userId);

// 推荐:分页传输
PageResult<Order> getOrders(Long userId, int page, int size);

// 3. 使用 DTO 减少传输字段
// 不推荐:传输 Entity(字段多)
User getUser(Long userId);

// 推荐:传输 DTO(只包含必要字段)
UserDTO getUser(Long userId);

2. 兼容性考虑

// Protobuf 的向后兼容性
message UserProto {
    int64 id = 1;
    string name = 2;
    int32 age = 3;
    
    // 新增字段,不影响旧版本
    string email = 4;  // 新版本添加
}

// 旧版本的客户端仍然可以正常工作
// 新字段会被忽略

3. 序列化异常处理

@Service
public class UserServiceImpl implements UserService {
    
    @Override
    public User getUser(Long userId) {
        User user = userMapper.selectById(userId);
        
        // 确保返回的对象可以被序列化
        if (user != null) {
            // 清理不能序列化的字段
            user.setTransientField(null);
        }
        
        return user;
    }
}

答题总结

Dubbo 支持的序列化方式及选择建议

1. 主要序列化方式(按推荐度)

  • hessian2:默认,性能与兼容性平衡 ⭐⭐⭐⭐
  • kryo:性能最优,Java 内部调用 ⭐⭐⭐⭐⭐
  • protobuf:跨语言最优,高性能 ⭐⭐⭐⭐⭐
  • fastjson/jackson:可读性好,调试友好 ⭐⭐⭐
  • fst:性能好,Java 内部使用 ⭐⭐⭐
  • jdk:不推荐,性能差 ❌

2. 选择建议

  • 常规场景 → hessian2(默认)
  • 高性能 → kryo
  • 跨语言 → protobuf + triple
  • 调试 → fastjson

3. 性能对比(速度和体积):

kryo > protobuf > hessian2 > fst > fastjson > jackson > jdk

4. 配置方式

@Service(serialization = "kryo")  // 服务级别

dubbo:
  protocol:
    serialization: hessian2  // 全局配置

面试技巧:强调 hessian2 是默认选择kryo 适合性能优化protobuf 适合跨语言。可以结合实际测试数据(速度、体积)说明差异,体现对性能优化的理解。