Pull to refresh

Comments 20

Автор оригинала собрал все в кучу SOA, ESB назвал это все MS и еще посыпал сверху «SAGA». Вы это все перевели и теперь кучка недоархитекторов будут нести это в русские массы.
Какие ваши доказательства?
Покажите код действительно рабочего надёжного решения энтерпрайзного уровня, а не hello-world.
Мне сага, например, тоже не нравится. Если в первом случае есть только общая точка отказа — менеджер транзакций а бизнес логика может быть распределена между микросервисами. То в случае саги наша бизнес логика перетекает полностью в хореографера — монолит от которого пытались уйти. Да еще и он является и общей точкой отказа.

По-идее, сагу тоже можно делать распределённой. Собственно, я так всегда и делал, не зная что у меня получается распределённая сага :-)

«Распределенная транзакция» сейчас считается анти-паттерном. Для меня вообще странно, что в 2020 году об этом паттерне говорят. Даже более того: имхо, это просто нерабочий паттерн. По одной простой причине — любой компонент системы когда-нибудь упадет. Рано или поздно упавший менеджер транзакций приведет к огромному геморою. Низкая производительность — тоже аргумент, но, с моей т.з., куда как менее важный.

По сути, другого выбора, кроме саги, в распределенных сервисах просто нет. Это может быть как формальная сага, так и сага по сути. В противном случае получите неконсистентные данные.
Хорошая статья. Только без знаний о распределенных блокировках которые через Redis например можно сделать и знаний о инструментах для создания Saga которые можно через MassTransit сделать она немного не полная.
В чем здесь отличие монолита от микросервисов? В том, что в случае монолита, ACID всегда у вас внутри (неважно, однофазные или двухфазные у вас транзакции) — и значит, вам больше не о чем волноваться. Для микросервисов же ACID все равно надо соблюсти, но уже на уровне отношения с пользователем (ему не понравится, если деньги за товар списались, а сообщение отказа со склада потерялось на шине). А это значит, что ACID в данном случае придется делать вам руками, разводя сложные цепочки эвентов от микросервисов, и анализируя их в стейт-машине вашей оркестрирующей или хореографирующей (и почему здесь терминология из мира оперы и балета?) прослойки. Следовательно, в случае монолита — ACID — разработанное гарантированно квалифицированными инженерами и проверенное миллионами транзакций стандартное средство общего применения. А в случае микросервисов — разработанное вашими коллегами под конкретную бизнес-транзакцию поделие, в лучшем случае покрытое юнит-тестами. Где брать пруф корректной работы вашего ACIDа для всех возможных случаев отказов и потерь сообщений?
Обычно, перед тем как пустится во все тяжкие, предстоит сделать выбор: либо железобетонный ACID и фактически монолит, либо микросервисы. На двух стульях усидеть очень сложно.
Поэтому меня смешит хайп безусловного распиливания монолитов. «Возьми перфоратор в руки и ощути себя Архитектором будущего». А потом собери свой собственный Шанхай на синей изоленте.
Нужно всегда отдавать себе отчет, какие свойства проектируемой системы критичны, и какие особенности автоматизируемых бизнес-процессов будут сложны в своей имплементации. Ибо есть очень интересное фундаментальное ограничение, вытекающее из теории информации — нельзя просто сделать сложное. Автоматизация сложного бизнес процесса будет как минимум не проще его самого.

Если нужны когерентные источники корректно-многосвязных данных — то без ACID будет очень сложно. С другой стороны, ACID дается очень дорого. Если из обычной БД откусить ACID, то она будет стрелять, как no-sql key-value пулемет. Поэтому, если когерентность вам не нужна, и транзакционность тоже не очень важна, и модель данных несложная — можно и распилить.
Просто полноценный ACID нужен не всем, часто хватает чего-то типа eventual consistency. И вот эти люди рассказывают на разных мероприятиях как им хорошо с микросервисам. А другие люди это слушают и необдуманно применяют к своим сценариям, где ACID нужен по бизнесу. И потом в муках рождаются разные саги и прочие паттерны.
Просто полноценный ACID нужен не всем, часто хватает чего-то типа eventual consistency.

С eventual consistency работать намного сложнее чем ACID. Мне неизвестна ни одна задача, которая при замене ACID на eventual consistency стала бы проще.
А не могли бы вы уточнить следующий вопрос, про двухфазную фиксацию: Допустим fail случился не в фазу prepare, а не отработал второй done, что будет? Ведь, как я понимаю, первый микросервис свою часть транзакции уже зафиксировал. Тут видимо все так очевидно, что не совсем понятно.

У Вас сообщение в event bus шине осталось. Она считается априори надежной. Теоретически можно всегда сходить в сервис, DONE которого потерялся, и запросить его повторно. Вопрос в том, что это совсем какая-то аварийная ситуация. И вероятно, что у Вас проблемы существенно более серьёзные, чем отсутствие единственного DONE


Если я Вас не понял — поясните, пожалуйста, свою мысль более развёрнуто

Я пытаюсь понять на пальцах как работает двухфазный коммит.
Теоретически можно всегда сходить в сервис, DONE которого потерялся, и запросить его повторно.
Я имею в виду случай когда второй DONE не потерялся, а вернулся с FAIL-ом.

Понял, Вы про 2PC с transaction coordinator (а не про сам атомарный 2PC внутри микросервиса). Тогда он просто откатывает все транзакции, которые идут в микросервисы....

Я имею ввиду следующую ситуацию:
1. Оба PREPARE прошли и вернули DONE. В этом момент изменение еще никто не видит из вне.
2. COMMITE первого сервиса прошел, а второй нет. В этой ситуации сторонни наблюдатель видит изменения в первом микросервисе, но не видит во втором. Я пока не вижу тут из чего вытекает общая атомарность общей транзакции. Можете пояснить пожалуйста?

У Вас атомарность обеспечивается тем, что внешний наблюдатель не ходит напрямую в оконечные микросервисы. Они ходят через фасад. Ну, и в конечном счете все равно надо писать так сервисы, чтобы изменение состояние в одном микросервисе (если все-таки кто-то ходит в них напрямую) не ломает всю систему целиком (ну, была заявка на заказ и резерв на товары — заказ сломался, снимаем заявку на заказ и резерв)

В данном случае, сторонний это — фигура речи, не нужно придираться к словам. Имеется в виду, что параллельно оркестратор может работать с 1000-ми разных запросов к микросервисам и сам оркестратор, в данном случае, является внешним наблюдателем по отношению к микросервису.
Давайте абстрактно, без всяких заказов, резервов и т.д. Допустим я оркестратор, у меня есть две БД и я пытаюсь транзакционно записать две записи в одну и другую базу. Транзакционно, это значит что они либо должны обе появиться и в одной БД и в другой, либо не появиться вовсе. Делаю PREPARE записи в одной БД — ок, делаю PREPARE записи в другой БД — ок. Пока что, если сделать параллельный запрос то записи не видны ни там ни там. Теперь я делаю DONE в первую БД — теперь запись появилась в одной БД, но второй записи еще нет во второй БД. Где тут транзакция? Из объяснения в статье этого не видно.
Будет рассинхронизация данных в ваших БД и много головной боли и будет это повторяться очень очень редко. А вот когда у вас сага и микросервисы и прочая годнота, то рассинхрон тоже будет, но значительно чаще.
Sign up to leave a comment.