Авро союз: прямая совместимость? - PullRequest
0 голосов
/ 30 января 2019

Наша система состоит из нескольких микросервисов, которые испускают и потребляют события, закодированные в формате avro (см. Схему внизу).Конкретный вариант использования следующий: служба A испускает событие (типа InvoiceEvents) по теме T1, а службы B и C (разные команды разработчиков) потребляют из T1.Например, Служба B является частью налоговой команды, а Служба C является частью команды по выполнению продукта.

Я ожидал, что следующее (правда, не так):

  1. Схема может эволюционировать от версии 1 (v1) до версии 2 (v2) путем добавления нового типа объединения (т. Е. InvoiceCreated для поля «полезная нагрузка»). - Изучите примеры схем внизу.
  2. создание службы A для обновления до версии v2 (т. е. создание событий, следующих за версией v2)
  3. Некоторые потребляющие службы (например, служба C) могут по-прежнему использовать версию v1, поскольку они не заинтересованы в новом типе события (например, InvoiceCreated).В этом случае в поле «полезная нагрузка» будет использоваться значение по умолчанию (нулевое) при десериализации.
  4. В конечном счете и только если это требуется по деловым причинам, служба 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 

Не совместимы ли типы австро объединения (как описано выше)?Являются ли они только обратно совместимыми, как следует из реестра Confluent Schema tests .Каким образом предлагается избежать связывания микросервисов?Я полагаю, авро-союзы не могут быть использованы ..

Спасибо !!

Связанная ссылка без однозначного ответа: Avro-union-compatibility-mode-Enhancement Предложение


схема v1:

[
   ...
   {
      "type":"record",
      "name":"InvoiceEvents",
      "namespace":"bla.bla.schema.avro.invoice",
      "fields":[
         {
            "name":"payload",
            "type":[
               "null",
               "bla.bla.schema.avro.invoice.InvoiceDrafted"
            ],
            "default":null
         }
      ]
   }
]

схема 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
         }
      ]
   }
]

1 Ответ

0 голосов
/ 31 января 2019

После некоторого размышления мы, вероятно, перейдем к варианту 3, так как отсутствие пропуска / потери событий для проекта важнее, чем разделение:

  1. Обработка исключений в пользовательском derserialiser и пропуск событий (могут потерять интересные события- Чтобы не потерять события, все службы-потребители должны быть обновлены до того, как будут созданы все службы)
  2. Преобразуйте все пользовательские объединения записей в отдельные необязательные поля (могут потеряться интересные события, так как изменения совместимы с прямой пересылкой, а службы-потребители не будут блокироваться)
  3. Принять ошибку десериализации / потребление блоков и версию повышения во всех потребляющих сервисах, которые используют схему для нового пользовательского типа записи (это гарантирует, что ни одно интересное событие не потеряно).

Пожалуйстапрокомментируйте, если есть лучший вариант, и я пропустил его!

...