多个系统消费OrderCreated事件。生产者准备新增promotionCode字段,但部分旧消费者暂时无法同步升级。已知旧消费者能够忽略未知可选字段,较稳妥的演进方式是()。
在题设的容错契约下,新增可选字段并保留原字段和语义,旧消费者可以继续处理事件。默认值、Schema版本和兼容性检查还能让新旧版本并行演进。
选项分析
错误。删除关键旧字段会破坏依赖orderId的消费者。
错误。无迁移地改变字段类型属于高风险破坏性变更。
正确。保留原契约并新增可选字段,配合兼容性检查,最利于渐进升级。
错误。私有格式会制造不可治理的分支契约和排障困难。
本题为什么容易错
“新增字段一定兼容”并不绝对。如果消费者采用严格封闭Schema,未知字段也可能失败;因此题目中特意给了“旧消费者忽略未知可选字段”这一前提。
简短答案
订单事件要新增字段,怎样避免旧消费者立即失效,正确答案是 C(新增promotionCode为可选字段并定义缺省语义,保留原字段,同时在发布前做兼容性检查)。在题设的容错契约下,新增可选字段并保留原字段和语义,旧消费者可以继续处理事件。默认值、Schema版本和兼容性检查还能让新旧版本并行演进。
易混淆概念对比表
| 概念 | 本题判断 | 区别要点 | 记忆提示 |
|---|---|---|---|
| 直接删除原orderId字段,用promotionCode替代 | 本题干扰项 | 错误。删除关键旧字段会破坏依赖orderId的消费者。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
| 把原有amount从数值改成结构复杂且无迁移说明的字符串 | 本题干扰项 | 错误。无迁移地改变字段类型属于高风险破坏性变更。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
| 新增promotionCode为可选字段并定义缺省语义,保留原字段,同时在发布前做兼容性检查 | 本题正确答案 | 正确。保留原契约并新增可选字段,配合兼容性检查,最利于渐进升级。 | 看到题干核心场景时优先联想到它 |
| 给旧消费者发送一套未登记的私有事件格式 | 本题干扰项 | 错误。私有格式会制造不可治理的分支契约和排障困难。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
本题易混淆选项怎么区分
- 直接删除原orderId字段,用promotionCode替代:错误。删除关键旧字段会破坏依赖orderId的消费者。
- 把原有amount从数值改成结构复杂且无迁移说明的字符串:错误。无迁移地改变字段类型属于高风险破坏性变更。
- 给旧消费者发送一套未登记的私有事件格式:错误。私有格式会制造不可治理的分支契约和排障困难。
知识点详解
事件Schema是生产者与消费者的长期契约。安全演进通常优先采用可选字段、明确默认值、保留既有语义和版本化Schema,并在注册或流水线中执行兼容性检查。删除字段、收窄类型、改变单位或枚举含义都可能破坏消费者。重大不兼容变更可通过新事件类型、双写迁移、消费者升级窗口和停用计划处理。
备考速记
加可选、留旧义、给默认、先检查;字段能读不代表语义没变。
Schema兼容 在事件驱动架构场景中的作用
promotionCode为空应明确表示“无促销”还是“未知”。如果缺省语义不清,即使反序列化成功,新旧系统也可能对同一订单作出不同判断。
同类题怎么考
- 判断事件字段变更是否破坏旧消费者。
- 比较向后兼容、向前兼容和完全兼容的读写方向。
Schema兼容 在系统架构设计师软考中的考法
看到Schema演进,先画新旧生产者和新旧消费者。选项若保留旧字段、增加可选字段并提供默认语义,通常更稳;删除、改名和改类型要有明确迁移版本。
解题思路
先站在旧消费者位置看新事件:它认识orderId和amount,不认识promotionCode,但题干已说明会忽略未知可选字段。因此保留旧字段,只新增带缺省语义的可选字段,旧代码仍能工作。删除、重命名和改变类型都可能让旧反序列化或业务逻辑出错,选 C。
考点定位
兼容性方向取决于谁读谁的数据。考试场景应先明确生产者和消费者版本,再判断新增、删除或改类型是否破坏契约。
易错提醒
- 字段名不变却改变单位,例如金额从元改为分,造成静默语义错误。
- 只和上一个Schema版本比较,没有检查长期未升级的消费者。
- 删除字段前没有统计真实消费者,也没有弃用窗口。
备考提示
- 每次演进都问:旧消费者能否读新事件,新消费者能否读旧事件。
- 把字段名称、类型、是否必填、默认值、单位和枚举范围一起当作契约。
你可能还想了解
- 事件新增字段一定向后兼容吗?
- 删除消息字段会影响哪些消费者?
- Schema兼容性为什么还要检查字段语义?
本文小结
旧消费者能忽略未知字段时,保留原字段并新增带缺省语义的可选字段,配合兼容性检查,可支持新旧消费者渐进升级。