【发布时间】:2019-01-30 11:15:15
【问题描述】:
我们的系统由多个微服务组成,它们发出和使用以 avro 格式编码的事件(参见底部的架构)。一个特定的用例如下:服务 A 在主题 T1 上发出一个事件(类型为 InvoiceEvents),服务 B 和 C(不同的开发团队)正在从 T1 消费。例如。服务 B 属于税务团队,而服务 C 属于产品履行团队。
我期待以下是真的(但似乎不是):
- 通过添加新的联合类型(即为字段“有效负载”创建 InvoiceCreated),架构可以从版本 1 (v1) 演变为版本 2 (v2) - 查看底部的示例架构。
- 生产服务 A 升级到 v2(即生产遵循 v2 的事件)
- 一些消费服务(例如服务 C)仍然可以使用 v1,因为它们对新的事件类型(例如 InvoiceCreated)不感兴趣。在这种情况下,“有效负载”字段在反序列化时将使用默认(空)值。
- 最终且仅在出于业务原因需要时,服务 C 才能升级到使用 v2,如果需要对新事件类型(即 InvoiceCreated)做出反应。
但服务 C 无法反序列化 InvoiceCreated 类型的新事件。具体来说就是抛出:
org.apache.avro.AvroTypeException: Found com.elsevier.q2c.schema.avro.invoice.InvoiceCreated, expecting unionorg.apache.avro.AvroTypeException: Found com.elsevier.q2c.schema.avro.invoice.InvoiceCreated, expecting union at org.apache.avro.io.ResolvingDecoder.doAction(ResolvingDecoder.java:292) at
avro 联合类型是否不向前兼容(如上所述)?它们是否仅像 Confluent Schema Registry tests 所暗示的那样向后兼容。避免微服务耦合的建议方法是什么?我猜无法使用 avro unions..
谢谢!!
没有明确答案的相关链接:Avro-union-compatibility-mode-enhancement-proposal
架构 v1:
[
...
{
"type":"record",
"name":"InvoiceEvents",
"namespace":"bla.bla.schema.avro.invoice",
"fields":[
{
"name":"payload",
"type":[
"null",
"bla.bla.schema.avro.invoice.InvoiceDrafted"
],
"default":null
}
]
}
]
schema v2(添加了新的联合类型:InvoiceCreated):
[
...
{
"type":"record",
"name":"InvoiceEvents",
"namespace":"bla.bla.schema.avro.invoice",
"fields":[
{
"name":"payload",
"type":[
"null",
"bla.bla.schema.avro.invoice.InvoiceDrafted",
"bla.bla.schema.avro.invoice.InvoiceCreated",
],
"default":null
}
]
}
]
【问题讨论】:
-
Avro specification 表示如果所选作者的联合模式不是读者联合中的模式之一,则发出错误信号。
-
确实在联合中添加新类型是不向前兼容的更改
标签: avro confluent-schema-registry