⚾️ 问题描述
在一次 Dubbo 微服务调用中,服务 A 调用服务 B 接口,返回结果中的部分字段在 Consumer 侧(A 服务)丢失,表现为值为
null,但在 Provider 侧(B 服务)正常。这种现象对业务产生了干扰,因此需要深入排查。🏉 环境与日志信息
所有微服务 JVM 版本
dubbo 配置
provider (B服务) 的 dubbo 配置
consumer (A服务)的 dubbo 配置
对应日志
B 服务上的日志打印
A 服务上的日志打印
其他相同时间段内的日志打印
DTO 类
🎱 初步分析
通过对比 Provider 与 Consumer 两侧的日志,发现 Provider 返回的日志完整,而 Consumer 却存在多个字段为
null 的情况,尤其是 code 和 level 等核心字段。这种现象显然不是业务逻辑导致,而可能与序列化或 DTO 对象兼容性有关。🤺 问题排查
在排查序列化问题之前,首先要明确在当前dubbo调用中,序列化协议使用的是什么。
首先看一下两个服务的相关配置
provider (A服务) 的 dubbo 配置
consumer (B服务)的 dubbo 配置
Provider 配置了
prefer.serialization=fastjson2,hessian2,但由于 Consumer 没有声明具体的 serialization,Dubbo 使用协议协商默认 fallback 为 Hessian2。重要说明:Dubbo 协议协商中,Consumer 配置优先于 Provider,Provider 无法强制指定 Consumer 使用特定序列化方式。
在dubbo-admin 查看对应服务的序列化方式,进一步确认为
hessian2
通过查询,进一步明确 dubbo 3.2.0 使用的 dubbo-hessian-lite 为 3.2.13 版本。
为确认是否为
CopyOnWriteArrayList 等线程安全集合或 DTO 差异导致的问题,构造本地 Demo 进行验证,部分代码如下:provider 模块
consumer 模块
demo运行结果显示,在dubbo3.2.0,dubbo-hessian-lite 3.2.13 版本中,DTO中的CopyOnWriteArrayList并不影响反序列化。

并且验证了以下几种情况,也并不影响序列化和反序列化。
1、consumer 中SystemDeviceErrorCodeListResponse.systemErrorCodeList和SystemDeviceErrorCodeListResponse.deviceErrorCodeList字段为List,provider 中为CopyOnWriteArrayList;
2、consumer 中DeviceErrorCodeDetailDTO缺少serialVersionUID
🚣 最终定位:DTO版本不一致导致
在进一步排查构建产物时发现,CI 环境中打包错误:某二方库引用了旧版本 DTO,字段定义与最新 Provider 版本不一致,导致 Consumer 反序列化出现字段为 null。
修复方式:统一依赖版本,确保构建产物使用最新 DTO 定义,问题消失。
🚴 总结与建议
- Dubbo 序列化方式需双方明确配置,避免 fallback 导致兼容性问题;
- CI 构建环境需加强依赖管理,防止错误引用旧版本类库;
- 使用 JSON/Protobuf 等显式格式序列化方式,可减少兼容性隐患;
- 尽量避免使用线程安全类(如 CopyOnWriteArrayList)做为 RPC 数据传输对象结构;
- 建议建立字段兼容性校验机制,确保 CI 构建包字段定义一致。
🚥 参考文章
- 作者:Yibin
- 链接:https://yibin.dev/article/21c60b50-99a4-8009-ae17-e5d0b35fad55
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章





