Вопрос:

Как обеспечить, чтобы благотворительные объекты были обратно совместимы?

java thrift microservices

1475 просмотра

1 ответ

3795 Репутация автора

В настоящее время мы используем благотворительность для развития наших микро-услуг. Когда я недавно столкнулся с этой проблемой ниже.

Предположим, что ниже находится экономичный контракт для объекта Summary, и есть API, который получает и обновляет сводку, используя переданный объект Summary.

Версия - 1.0

struct Summary {
    1: required string summaryId,
    2: required i32 summaryCost
}

Summary getSummary(1: string summaryId);

void updateSummary(1: Summary summary);

Теперь предположим, что есть 5 сервисов, которые используют этот контракт 1.0 .
В следующем выпуске мы добавим еще один объект, называемый списком сводных значений .

Таким образом, новый контракт будет выглядеть

Версия - 2.0

struct Summary {
    1: required string summaryId,
    2: required i32 summaryCost,
    3: optional list<i32> summaryValues
}

Summary getSummary(1: string summaryId);

void updateSummary(1: Summary summary);
  1. Поэтому , когда это ниже список заполняется, мы сохраняем список значений summaryValuesaganist что summaryId.
  2. И когда клиент отправляет этот список, nullмы удаляем существующие значения, сохраненные для этого «summaryId».

Теперь проблема возникает, когда другие сервисы, использующие более старую версию контракта ( версия 1.0 ), пытаются вызвать getSummary и updateSummary.
Намерение Старшего Клиента путем вызова updateSummary состояло в том, чтобы установить другое значение для summaryCost. Однако, поскольку этот клиент не содержит объект, summaryValuesон отправляет объект Summary с summaryValuesнулевым значением на сервер.

Это приводит к тому, что Сервер удаляет все существующие значения summaryValuesдля этого summaryId.

Есть ли способ справиться с этим в бережливости? Методы isSet () здесь не работают, так как они пытаются выполнить простую нулевую проверку.
Каждый раз, когда мы выпускаем новый клиент с модификацией существующих объектов, нам приходится принудительно обновлять версии клиентов других серверов, даже если это изменение не связано с ними.

Автор: Bandi Kishore Источник Размещён: 22.08.2016 08:31

Ответы (1)


3 плюса

857 Репутация автора

В вашем version 2.0договоре updateSummary()метод изменился (т.е. теперь он позволяет сохранять и удалять итоговые значения):

Вариант 1. Вместо того, чтобы изменять его поведение, создайте новый метод (т. Е. updateSummaryV2()) И начните использовать его в последней версии ваших клиентов, но не используйте старую.

Таким образом, старые версии клиента по-прежнему используют обычные, updateSummary()не вступая в противоречие с контрактом и допущениями нового метода.


Вариант 2. Добавьте необязательное поле, содержащее версию API и значение по умолчанию, установленное на последнюю версию API:

struct Summary {
    1: required string summaryId,
    2: required i32 summaryCost,
    3: optional list<i32> summaryValues
    4: optional i32 apiVersion = 2
}

Таким образом, если apiVersionон не установлен, вы знаете, что запрос поступил от старого клиента, и для будущих версий вы будете знать версию клиента и можете реагировать соответствующим образом.


В качестве альтернативы вы можете удалить записи, только если предоставлен пустой список, и ничего не делать, если список не задан, чтобы соблюдать предыдущий контракт метода.

В качестве дополнительного примечания: наличие действия, зависящего от чего-то неявного (в данном случае, отсутствие списка), может быть в целом рискованным, даже без учета проблемы перекрестной совместимости. Как правило, безопаснее (и легче работать и поддерживать), когда такие действия зависят от явного флага.

Автор: Shastick Размещён: 05.11.2016 10:09
Вопросы из категории :
32x32