Межсервисные транзакции или атомарность

У меня есть программа в реальном времени, которая делает сетевые вызовы службы A для выполнения действия с отслеживанием состояния и сетевые вызовы службы B для регистрации истории этого действия. Подвох в том, что:

  1. Мы должны отменить действие A, если B терпит неудачу (по «причинам» нам нужна полная история, иначе действие вообще не может произойти). Другими словами, мы не можем написать контрольный журнал, если мы точно и успешно не вызвали службу для выполнения действия (т. е. мы не можем изменить порядок, чтобы сначала вызвать контрольный журнал, а затем вызвать службу).
  2. В B есть недопустимые порядки истории, которых у нас быть не может (это аспект состояния A)

У меня было несколько мыслей, ни одна из которых не была идеальной:

  • Получите статус A перед выполнением действия (это доступный метод), и если вызов B завершится ошибкой, мы можем просто снова вызвать первую службу с исходным состоянием. Проблема подхода заключается в том, что вызов «возврата» к A также может завершиться ошибкой.
  • На высоком уровне это кажется решаемым с помощью «транзакций» на уровне службы (где оба вызова службы выполняются успешно или оба терпят неудачу). Похоже, что основным алгоритмом является 2-этапная фиксация, но мы не можем его использовать, потому что мы не владеем сервисами, которые мы вызываем, поэтому нет гарантии стабильного хранения, и мы не можем добавить функциональность для «согласия». " с "координатором сделки"
  • Реализовать нашу собственную изощренную имитацию транзакций на нашей стороне. Мне кажется, что это довольно сложный подход, который было бы трудно или невозможно реализовать правильно.
  • Иметь возможность попасть в «в конечном счете согласованное состояние». Однако, согласно пункту 2, некоторые заказы невозможны, поэтому нам придется дождаться выполнения всех действий в очереди, прежде чем продолжить. Это сделало бы наш сервис потенциально не в режиме реального времени.

Есть ли решение, в котором мы можем получить полное зеркало журналов, удовлетворяющее требованиям со 100% точностью?

Что такое управление транзакциями JDBC и как оно используется для поддержания согласованности данных?
Что такое управление транзакциями JDBC и как оно используется для поддержания согласованности данных?
Управление транзакциями JDBC - это мощная функция, которая позволяет рассматривать группу операций с базой данных как единую единицу работы. Оно...
0
0
37
1

Ответы 1

Вы не упомянули протокол, по которому общаются все ваши службы, ради этого ответа я предполагаю HTTP.

Как вы сказали, ни одно из ваших возможных решений не звучит так, как будто они сработают для вас.

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

  2. Я думаю, что в сценарии, который вы описали, о двухфазной фиксации не может быть и речи. даже если вы владеете всеми сервисами, сложно сделать это правильно, используя только HTTP.

  3. я согласен

  4. Из всех вариантов у этого есть ноги. Все зависит от ваших требований к «реальному времени». Всякий раз, когда кто-то говорит это, я спрашиваю: «Что вы имеете в виду?» ничто не происходит в режиме реального времени, все требует времени для обработки. Всегда есть период времени, когда кто-то или что-то просит что-то сделать, чтобы это действительно было сделано! разница между миллисекундами, секундами и минутами - это просто вопрос требований и того, сколько денег вы должны разбрасывать.

Итак, вы говорите, что вызов вашей службы (давайте назовем ее X) через HTTP синхронно снова вызывает две службы A и B через HTTP. Если у вас есть много вызовов X одновременно, нет способа (или, по крайней мере, это очень сложно) гарантировать, что порядок вызовов A приводит к тому же порядку вызовов B. Но это снова зависит от ваших требований и того, что система поживает и как, может в вашу систему каждый день поступает только один звонок?

Лично я бы рекомендовал использовать очереди и перейти к архитектуре, управляемой событиями. Даже с стабильной системой вы можете заставить ее работать в горячем режиме и получать «реальное время», которое вы желаете, это будет стоить вам дороже!

Я надеюсь, что это было полезно для вас. Мне очень интересно услышать ваше мнение относительно моих предложений.

Я думаю, что минуты - это приемлемое время для ожидания, и трафик не должен быть слишком высоким. Хотя я думаю, что потребуются значительные усилия для разработки решения, обеспечивающего устойчивую локальную очередь.

Lycus 17.03.2019 23:43

Существует так много технологий, которые помогут вам в этой области, что вы не будете разрабатывать новое решение для этого. Просто взгляните на все технологии, доступные сегодня у облачных провайдеров. Мы активно используем sqs в AWS, и если вы работаете в локальной среде, вы можете использовать множество вариантов kafka, zeroMQ или rabbitMQ. разработка системы, управляемой событиями, проще, чем вы думаете.

Damo 18.03.2019 10:20

Другие вопросы по теме