Почему двухэтапная фиксация не подходит для архитектуры микросервисов?

Я прочитал сообщение, в котором говорится, что:

Мы не можем реализовать традиционную систему транзакций, такую ​​как двухфазная фиксация в микросервисах в распределенной среде.

Я полностью согласен с этим.

Но было бы здорово, если бы кто-нибудь здесь смог объяснить точную причину этого. С какими проблемами я столкнусь, если буду реализовывать двухэтапную фиксацию с помощью микросервисов?

заранее спасибо


comment
Я не эксперт, также не знаю, как точно ответить на все вопросы по этому вопросу, но, IMO, это чисто от того, как основана архитектура. Например, невозможно узнать, какая служба обработала вашу транзакцию на этапе 1 для опроса и повторного запроса подтверждения. Обычно вы вызываете шлюз API, который будет указывать на N экземпляров запущенной службы.   -  person nullptr    schedule 19.03.2019
comment
Вы согласны, но не знаете почему?   -  person user207421    schedule 20.03.2019


Ответы (5)


Некоторые моменты, на которые следует обратить внимание, а также дать некоторую предысторию:

  1. В большинстве сценариев микросервисы взаимодействуют через HTTP (протокол без сохранения состояния), и в результате глобальные транзакции / XA просто не применимы / невозможны.
  2. Ровно один раз семантика невозможна, и вы должны пойти хотя бы один раз. Это означает, что все службы должны быть идемпотентными.
  3. Одним из хороших примеров того, почему невозможно достичь семантики ровно один раз в такой настройке, является то, что HTTP-соединения очень часто теряются на обратном пути к клиенту. Это означает, что через POST состояние сервера изменилось, а клиент получил ошибку тайм-аута.
  4. Внутри микросервисов вы можете прекрасно ими пользоваться. Как вы упомянули Kafka, вы можете довольно легко использовать (из 1 темы) и производить (для 1 или более тем) одну атомарную операцию / все или ничего (семантика ровно один раз).
  5. Но если вам нужны глобальные и длительные транзакции между микросервисами, которые взаимодействуют через http, единственный практический вариант (вы можете увидеть глобальные транзакции через http, если вы используете Google, но для производственной системы просто игнорируете их), - это разработка для конечной согласованности. Вкратце, это означает, что нужно постоянно повторять попытки исправить исправимые ошибки (это отдельная глава) и открывать компенсирующие конечные точки или производить компенсирующие события, которые в конечном итоге исправят неисправимые ошибки. Ознакомьтесь с шаблоном саг. Narayana Transaction Manager имеет хорошую поддержку Sagas и хорошее сравнение продуктов .
  6. Ознакомьтесь с соответствующими шаблонами микросервисов, которые предлагают альтернативу транзакциям XA (вы можете увидеть это как глобальные транзакции или двухфазную фиксацию / 2PC), например Transactional Outbox или Источник событий которые предлагают хоть раз симпатичную семантику.
  7. Распределенные системы очень сложны, и у вас должна быть причина выбрать такое решение. Если вы идете распределенным, то операции, которые ваш монолит может безопасно делегировать вашему менеджеру транзакций, должны будут выполняться разработчиком / архитектором :-).
  8. Кроме того, большинство баз данных / систем, отличных от SQL, вообще не поддерживают транзакции XA (т. Е. Глобальные транзакции), поскольку они значительно замедляют обработку.
person Vassilis    schedule 20.03.2019

Основная причина, по которой следует избегать двухэтапной фиксации, заключается в том, что координатор транзакций является своего рода диктатором, поскольку он сообщает всем остальным узлам, что им делать. Обычно координатор транзакций встроен в сервер приложений. Проблема возникает, когда после 1-го этапа или этапа подготовки координатор транзакций или сервер приложений выходит из строя. Теперь участвующие узлы не знают, что делать. Они не могут выполнить фиксацию, потому что не знают, ответили ли другие координатору «нет», и они не могут выполнить откат, потому что другие могли сказать координатору «да». Таким образом, пока координатор не вернется через 15 минут (скажем) и не завершит вторую фазу, участвующие хранилища данных будут оставаться в заблокированном состоянии. Это снижает масштабируемость и производительность. Хуже всего происходит, когда журнал транзакций координатора повреждается после 1-го этапа. В этом случае хранилища данных навсегда останутся в заблокированном состоянии. Даже перезапуск процессов не поможет. Единственное решение - вручную проверить данные для обеспечения согласованности, а затем снять блокировки. Обычно это происходит в ситуации высокого давления, и поэтому это определенно огромные эксплуатационные расходы. Следовательно, традиционная двухэтапная фиксация не является хорошим решением.

Однако здесь следует отметить, что в некоторых современных системах, таких как Kafka, также реализована двухэтапная фиксация. Но это отличается от традиционного решения тем, что здесь каждый брокер может быть координатором, и, таким образом, алгоритм выбора лидера Kafka и модель репликации устраняют проблемы, упомянутые в традиционной модели.

person Saptarshi Basu    schedule 20.03.2019

Вся идея микросервисов - это слабосвязанные и независимые сервисы. Поскольку 2pc означает, что у нас есть 2 фазы для фиксации транзакции. управляющий узел будет управлять транзакцией, и все остальные узлы сначала ответят, что они готовы, а на втором этапе они все фиксируют или откатываются в зависимости от первого этапа.

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

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

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

person Imran Arshad    schedule 19.03.2019

«Мы не можем» здесь на самом деле означает: «Это плохая идея, и я не хочу, и если я допущу такую ​​возможность, то, возможно, мне не удастся убедить вас не настаивать».

Конечно, вы можете реализовать двухэтапную фиксацию для микросервисов, но:

  • Двухэтапная фиксация требует значительных усилий по разработке каждой службы, которая может участвовать в транзакции,
  • Это вызывает много конфликтов между клиентами, которые растут с задержкой связи между серверами; а также
  • Все задействованные службы должны согласовать множество протоколов, конфигурации, развертывания и других деталей, которые определяют, как на самом деле будет работать двухэтапная фиксация.

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

person Matt Timmermans    schedule 20.03.2019

Я бы предположил, что дело не в том, что мы не можем реализовать XA или 2PC для микросервисов, а в том, что мир API на основе HTTP еще не был политически приемлемым. В более старом приложении компоненты могут представлять собой более широкий набор сложных шагов бизнес-логики, а также охват, оборудование, географию, организации и технологии. то есть мои бизнес-компоненты могут быть распределены по нескольким компаниям с разными пользовательскими интерфейсами в каждой. Сетевые протоколы для интеграции всех этих поддерживаемых распределенных транзакций (2PC), а также распространения идентификаторов пользователей и т. Д.

Это связано с бюрократией и наследием. Стандартизованные распределенные транзакции, поддерживаемые несколькими совместимыми платформами, восходят к 80-м годам. ИТ в значительной степени движимы модой, что бы произошло на вашем рабочем месте, если бы вы слишком активно отстаивали этот тип функций.

Примечание: по вопросу о том, что произойдет, если управляющий узел выйдет из строя. В традиционных приложениях, если компонент, фиксирующий приложение, умирает в середине фиксации, транзакция в конечном итоге истекает по таймауту и ​​откатывается для каждого из компонентов. В некоторых случаях были доступны восстанавливаемые функции транзакций. если коммиттер восстановился до истечения тайм-аута, он восстановит транзакцию и продолжит фиксацию. Мы часто наблюдаем это в корпоративных приложениях: если сервер приложений отказывает, он восстанавливает внутрипроцессную работу.

пока я в настроении разглагольствовать :) - некоторые эксперты утверждают, что XA должен быть реализован на единой платформе, такой как JTA. Я никогда не считал, что это правда, XA всегда работал для меня без проблем с базами данных, серверами приложений и мэйнфреймами)

person Chris    schedule 17.02.2021