接口兼容与版本升级
2026年9月14日 上午5:33:29
RPC 的接口和 DTO 是客户端、服务端共同依赖的协议。一次改动可能同时影响 Java 方法代理、HTTP 路由和序列化格式。
1、 共享模块怎么放
user-api
├── UserService.java
└── User.java
只放接口、DTO、枚举和协议常量。不要把数据库实体、Mapper、服务实现、Web 容器和注册中心客户端放进去。这样客户端升级协议时不会被迫升级服务端实现依赖。
2、 相对安全的变更
- DTO 新增可选字段,旧客户端通常可以忽略。
- 新增接口路径或新方法,保留旧接口一段时间。
- 新增方法尽量使用不同名称,避免重载带来的方法元数据和映射歧义。
- 服务端先兼容旧客户端,再发布客户端。
3、 高风险变更
以下改动应视为不兼容,至少要做双版本或灰度验证:
- 修改
@Mapping路径或@NamiMapping的 HTTP 方法。 - 修改参数名、路径变量、query/body 位置。
- 修改返回类型、字段类型、枚举值语义。
- 删除旧字段,或把必填字段改成旧版本无法理解的类型。
- 只升级一端的二进制序列化组件。
4、 协议示例
旧接口:
public interface UserService {
User getById(long userId);
}
新增能力时优先增加新方法,而不是改变原方法返回值:
public interface UserService {
User getById(long userId);
UserDetail getDetailById(long userId);
}
服务端先实现并发布,确认旧客户端仍能调用,再发布依赖新方法的客户端。
5、 序列化兼容测试
升级前至少验证:
- 基本类型、集合、null 和空集合。
- 日期、枚举、嵌套 DTO。
- 新 DTO 读取旧响应,旧 DTO 读取新增字段后的响应。
- 400/500 错误响应是否仍能被客户端识别。
- HTTP + snack4 与实际部署依赖是否一致。
建议保存脱敏的请求/响应样本,建立 provider/client 的集成测试,不要只依赖“本地能启动”。
6、 推荐发布顺序
发布兼容版服务端
↓
观察旧客户端和错误率
↓
发布新客户端
↓
确认无旧客户端后再删除旧接口
如果更换 channel、coder、serialization 或 Discovery 插件,应单独做回滚方案。当前仓库源码中的 Nami 核心 API 包括 Nami.builder()、NamiBuilder.create、@NamiClient、@NamiMapping、@NamiBody 和 NamiAttach;升级时应以目标版本源码为准,不要把旧资料中的 NamiAttachment 当成 4.x API。