微服务之间传对象、Redis 存对象、Kafka 发消息时,你们怎么选择序列化方式?踩过什么坑?
我的判断
序列化方案按链路寿命和兼容要求选择:RPC 重类型约束,Kafka 重长期演进,Redis 重版本与可清理,不能一套格式到处复用。
服务间 RPC 如果双方都是内部系统,我会优先使用有 schema 的 Protobuf;需要人肉排查、跨语言接入频繁时会用 JSON,但字段、时间和金额格式要固定。Kafka 事件会保存 eventType、schemaVersion、业务主键和发生时间,因为消息可能几个月后还要重放,消费者必须能兼容旧字段。
Redis 里我不会直接塞 Java 原生序列化对象。它和类名、serialVersionUID 绑得太死,还存在安全与跨语言问题。更常见的做法是存紧凑 JSON/Protobuf,并把版本放进 key 或 value;不兼容升级时双读或换 key 前缀,让旧缓存自然过期。
上线前会做兼容测试:
- 新消费者读取旧消息;
- 旧消费者忽略新增字段;
- 枚举出现未知值时不直接崩溃;
- 大对象的序列化耗时、消息大小和 Redis 内存都在预算内。
序列化失败要进死信或隔离队列,不能跳过后继续提交位点,否则一条坏消息会被悄悄丢掉。