{"name":"couponId","type":["null","string"],"default":null}
curl -s -X POST -H 'Content-Type: application/vnd.schemaregistry.v1+json' \
  --data @schema.json http://registry:8081/compatibility/subjects/orders-value/versions/latest

给订单事件加了个 couponId 字段,生产者启动时报 SchemaCompatibilityException: Reader schema missing default value for couponId,注册被拒,整个应用起不来。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,Avro 的向后兼容要求新字段有默认值,老数据里没有这个键,读取端得知道用什么补。没有 default 就只能判定为不兼容,registry 拒绝注册。

「Avro schema 兼容」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。

验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。

处理上按这个顺序:给新字段补上 default null 并允许 union 里带 null;确认兼容级别是 BACKWARD 还是 FULL 别随手改成 NONE;在测试环境用旧 schema 读新数据 反向再读一遍;字段只增不删 要删先标记 deprecated 并保留编号。

改完只确认一件事:新 schema 注册成功 用旧数据读新结构时 couponId 是 null 不抛异常。

作者 9823189