Ооо, я уже несколько лет мучаюсь теорией распределенных транзакций в микросервисной архитектуре. Ковырял всякие 2PC и 3PC, вплоть до университетских трудов (например). Пытался что-то додумать сам, идея идемпотентных токенов и сервиса, который их выдает, тоже возникла, но до чего-либо вменяемого даже на уровне теории допилить не удалось. Поэтому, заголовок выглядел весьма многобещающим.
Тем не менее, прочитав саму статью, а также материалы по ссылкам, вопросы к самому базовому сценарию, с практической точки зрения, у меня остаются. Давайте рассмотрим следующий кейс. Для упрощения, будем считать, что проект мы пишем полностью с нуля (распиливать монолит и поддерживать легаси не нужно), среда гомогенна (зоопарка технологий тоже нету, цель применения микросервисной архитектуры — масштабирование, отказоустойчивость, изоляция кодовой базы). Очевидно также, что используется database-per-service паттерн, и затрагивается в первую очередь вопрос распределенной записи — с чтениями все сильно проще (грязные чтения и прочие радости жизни, возникающие от отсутствия изоляционности, пока оставим за кадром).
Итак, требуется реализовать систему регистрации и авторизации пользователей, с SSO. Допустим, у нас есть Web/Mobile UI (это важно). Имеем какой-либо entry point, пускай /api/users/register. Этот сервис выступает в роли координатора, своего хранилища данных не имеет. Есть сервис SSO, реализованный, к примеру, через IdentityServer — то есть, держит общую информацию, требуемую для логина пользователя, также, отвечает за выдачу логин-токенов, и есть возможность дописывать кастомную логику. Второй сервис отвечает за регистрационную информацию, требуемую конкретному проекту, вне SSO. Чуть-чуть усложним — добавим третий сервис, который по завершении процесса отсылает емейл свежезарегистрированному пользователю. Иными словами, фронт-энд запрашивает операцию записи у координатора, а тому требуется внести записи в две БД, через соотвествующие сервисы, отправить письмо пользователю, и вернуть результат клиентской стороне. Требуется обеспечить консистентность данных (eventual, конечно же), и хороший UX.
Считаем, что сами сервисы обеспечивают транзакционность (NoSQL пока трогать не будем), но любой из сервисов в любом количестве может упасть или перестать отвечать.
Собственно, вопросы:
— что минимально потребуется добавить для реализации данного сценария?
— а не минимально? Какие дополнительные возможности можно получить?
— как именно это должно работать, в плане синхронности/асинхронности, протоколов/софта? Другими словами — REST будет достаточно, или потребуется AMQP? RabbitMQ — хватит, или Kafka — без вариантов? Сервис саги как таковой разве не должен реализовывать персистентную очередь?
— можно ли избежать необходимости в компенсационности? Пример — отсылка мейла — это действие плохо откатывается. Можно ли строить архитектуру по принципу того, что рано или поздно сервисы поднимутся, и обработают накопившиеся в очереди сообщения?
— туда же — есть ли жизнь без event sourcing? Если есть — какие альтернативы DELETE запросу / маркированию сущности как удаленной?
— как обеспечить хороший пользовательский опыт, учитывая, что, во-первых, клиенту требуется вернуть синхронный ответ от координатора, но операции у нас, скорее всего, асинхронные, а во-вторых, часть операций может выполниться, а часть — нет? Мне приходят в голову только какие-то жуткие идеи с веб-сокетами, и сообщениями в стиле «Процесс регистрации завершен частично. Мы отправим Вам сообщение на электронную почту, как только все будет готово». Наверное, этот вопрос как-то решен, нет?
Тем не менее, прочитав саму статью, а также материалы по ссылкам, вопросы к самому базовому сценарию, с практической точки зрения, у меня остаются. Давайте рассмотрим следующий кейс. Для упрощения, будем считать, что проект мы пишем полностью с нуля (распиливать монолит и поддерживать легаси не нужно), среда гомогенна (зоопарка технологий тоже нету, цель применения микросервисной архитектуры — масштабирование, отказоустойчивость, изоляция кодовой базы). Очевидно также, что используется database-per-service паттерн, и затрагивается в первую очередь вопрос распределенной записи — с чтениями все сильно проще (грязные чтения и прочие радости жизни, возникающие от отсутствия изоляционности, пока оставим за кадром).
Итак, требуется реализовать систему регистрации и авторизации пользователей, с SSO. Допустим, у нас есть Web/Mobile UI (это важно). Имеем какой-либо entry point, пускай /api/users/register. Этот сервис выступает в роли координатора, своего хранилища данных не имеет. Есть сервис SSO, реализованный, к примеру, через IdentityServer — то есть, держит общую информацию, требуемую для логина пользователя, также, отвечает за выдачу логин-токенов, и есть возможность дописывать кастомную логику. Второй сервис отвечает за регистрационную информацию, требуемую конкретному проекту, вне SSO. Чуть-чуть усложним — добавим третий сервис, который по завершении процесса отсылает емейл свежезарегистрированному пользователю. Иными словами, фронт-энд запрашивает операцию записи у координатора, а тому требуется внести записи в две БД, через соотвествующие сервисы, отправить письмо пользователю, и вернуть результат клиентской стороне. Требуется обеспечить консистентность данных (eventual, конечно же), и хороший UX.
Считаем, что сами сервисы обеспечивают транзакционность (NoSQL пока трогать не будем), но любой из сервисов в любом количестве может упасть или перестать отвечать.
Собственно, вопросы:
— что минимально потребуется добавить для реализации данного сценария?
— а не минимально? Какие дополнительные возможности можно получить?
— как именно это должно работать, в плане синхронности/асинхронности, протоколов/софта? Другими словами — REST будет достаточно, или потребуется AMQP? RabbitMQ — хватит, или Kafka — без вариантов? Сервис саги как таковой разве не должен реализовывать персистентную очередь?
— можно ли избежать необходимости в компенсационности? Пример — отсылка мейла — это действие плохо откатывается. Можно ли строить архитектуру по принципу того, что рано или поздно сервисы поднимутся, и обработают накопившиеся в очереди сообщения?
— туда же — есть ли жизнь без event sourcing? Если есть — какие альтернативы DELETE запросу / маркированию сущности как удаленной?
— как обеспечить хороший пользовательский опыт, учитывая, что, во-первых, клиенту требуется вернуть синхронный ответ от координатора, но операции у нас, скорее всего, асинхронные, а во-вторых, часть операций может выполниться, а часть — нет? Мне приходят в голову только какие-то жуткие идеи с веб-сокетами, и сообщениями в стиле «Процесс регистрации завершен частично. Мы отправим Вам сообщение на электронную почту, как только все будет готово». Наверное, этот вопрос как-то решен, нет?
Спасибо!