Такой вопрос. Когда падает база — то ладно, как бы можно смириться что все не работает — ни заказ не сделать ни даже сайт ни открыть.
А вот когда падает EventBroker а база работает — как поведет ваша система?
К примеру, у вас сделано так, что после создания заказа создается событие через EventBroker и подписчики его обрабатывают. Но! А если событие не удалось создать — заказ повиснет навсегда?
Или же второй вариант — сделать спец. флаг, который устанавливать если событие было успешно опубликовано. А если флаг не установлен и прошло более n сек — то по таймеру опять публиковать до победного конца.
Здравствуйте, Shmj, Вы писали:
S>А если событие не удалось создать — заказ повиснет навсегда?
Ну в первую очередь — механизим retry никто не отменял.
Другое дело откуда запрос на публикацию event пришел.
* если вызывающая сторона ждет завершения публикации — несколько коротких retry и если не прошло, то откатываем транзакцию и фейлим процесс (например, это команда вызванная из API и которая ждет завершения чтобы вернуть HTTP response).
* если завершения текущего процесса никто не ждет (пример — event handler) и по BL можно подождать, то просто retry растягиваются насколько это восможно по логике процесса. не помогли retry — падаем, но тут уже все зависит от деталей текущего бизнес процесса. Где-то можно просто записью в лог обойтись, а где-то придется может что-то и в БД записать.
Re[2]: Сломается ли ваша система, если упадет EventBroker?
Здравствуйте, Doc, Вы писали:
Doc>* если завершения текущего процесса никто не ждет (пример — event handler) и по BL можно подождать, то просто retry растягиваются насколько это восможно по логике процесса. не помогли retry — падаем, но тут уже все зависит от деталей текущего бизнес процесса. Где-то можно просто записью в лог обойтись, а где-то придется может что-то и в БД записать.
Немного не нравится что нужно держать транзакцию — как правило транзакция так же держит блокировку на некоторых данных.
Re: Сломается ли ваша система, если упадет EventBroker?
Здравствуйте, Shmj, Вы писали:
S>А вот когда падает EventBroker а база работает — как поведет ваша система? S>К примеру, у вас сделано так, что после создания заказа создается событие через EventBroker и подписчики его обрабатывают. Но! А если событие не удалось создать — заказ повиснет навсегда?
Отправитель несет ответственность за доставку. Если брокер не работает, то отправитель должен сохранить событие к себе в базу и позже, когда брокере оживет, отправить сообщение.
Best regards, Буравчик
Re[2]: Сломается ли ваша система, если упадет EventBroker?
Здравствуйте, Буравчик, Вы писали:
Б>Отправитель несет ответственность за доставку. Если брокер не работает, то отправитель должен сохранить событие к себе в базу и позже, когда брокере оживет, отправить сообщение.
По логике вещей так. Но тогда придется несколько дублировать механизм EventBroker — хранить события уже в базе а так же делать некий процесс, который будет проверять все ли отправлено и если нет — то доотправлять.
Re[3]: Сломается ли ваша система, если упадет EventBroker?
Здравствуйте, Shmj, Вы писали:
S>По логике вещей так. Но тогда придется несколько дублировать механизм EventBroker — хранить события уже в базе а так же делать некий процесс, который будет проверять все ли отправлено и если нет — то доотправлять.
Зависит от требований к сервису. Если не хочешь принимать риск падения брокера, то да, придется создавать свой (локальный) механизм.
Best regards, Буравчик
Re[3]: Сломается ли ваша система, если упадет EventBroker?
Здравствуйте, Shmj, Вы писали:
S>Немного не нравится что нужно держать транзакцию — как правило транзакция так же держит блокировку на некоторых данных.
Здравствуйте, Буравчик, Вы писали:
Б>Отправитель несет ответственность за доставку. Если брокер не работает, то отправитель должен сохранить событие к себе в базу и позже, когда брокере оживет, отправить сообщение.
Это руками будем делать? А если упадет база? Будем писать в другую базу? We need to go deeper?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Сломается ли ваша система, если упадет EventBroker?
Для этого вам придется делать доп. механизм — таблицу, куда будете сохранять сообщения + фоновый воркер, который из этой таблицы будет дергать и публиковать.
Еще немного и вы переизобретёте свой EventBroker.
Re[2]: Сломается ли ваша система, если упадет EventBroker?
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Обеспечивают, за счет кластеризации, приемлемое SLA у самого брокера. У клиента брокера, если что то пошло не так — репорт отказа в обслуживании.
Цитата из книги Ричардсон К. Микросервисы. Паттерны разработки и рефакторинга:
Как описывалось в главе 3, доступность системы —
это произведение доступности всех участников транзакции. Если в распределенной
транзакции участвуют два сервиса с доступностью 99,5 %, общая доступность будет
99 %, что намного меньше.
Там предлагают эту проблему решать использование шаблона «Повествование».
Re[3]: Сломается ли ваша система, если упадет EventBroker?
Здравствуйте, Shmj, Вы писали:
S>Еще немного и вы переизобретёте свой EventBroker.
Не совсем. Вообще говоря, в любой архитектуре, где есть взаимодействие сервисов, "внешний вызов", изменяющий состояние, обязан делаться в соответствии с REST-паттерном.
То есть именно так:
1. Записали в своё персистентное состояние "я планирую сделать вызов сервиса X с аргументами W, Y, Z", commit.
2. Попробовали выполнить вызов. Если удалось — записали в свое персистентное состояние "я получил от сервиса X результат R". Commit.
3. Продолжаем выполнять бизнес-логику над результатом R. Все моменты взаимодействия со внешними сервисами выполняем в соответствии с шагами 1-2.
4. При каждом старте нашего сервиса, инициализируем все стейт-машины для каждого из workflow, и продолжаем с того места, на котором был выполнен последний Commit. В частности, если видим запись, сделанную на шаге 1, выполняем шаг 2 и далее. Если видим запись, сделанную на шаге 2, выполняем шаг 3 и далее.
5. Альтернативный вариант — не делать автоматический старт, а возвращаться к workflow при получении повторного вызова с теми же аргументами. Логика простая: вот у нас попросили зарезервировать авиабилеты; на полпути выполнение нашего кода было прервано:
— внешний сервис был недоступен, мы вернули клиенту 5xx.
— внешний сервис сделал всё как надо, но наш сервис упал из-за ошибки или был перезапущен
В любом случае, клиент не получил ни 4xx, ни 2xx, поэтому он будет продолжать долбить нас с теми же параметрами.
И вот это даёт нам шанс поднять своё состояние, типа "так, на чём мы остановились. Ага, на первый рейс билеты забронированы, на второй — непонятно. Видно, что мы планировали сделать вызов, но результата вызова нет. Давайте повторно долбить сервис бронирования второго рейса".
Вот это всё — основа архитектуры. Полагаться можно только на своё собственное persistent-хранилище; отсутствие связи с ним — критическая ошибка, продолжать работу невозможно.
Event Broker не снимает с вас обязанности отслеживать успешность внешних вызовов — это точно такой же внешний сервис, как и любой другой.
Он снимает с вас заботу о поисках того сервиса, которому вы обязаны сообщить об изменениях вашего состояния.
То есть вы сообщили — а кто там слушает ваши события, и, к примеру, генерирует накладные на оплату для успешных бронирований, отправляет письма об этом, и т.п. — не забота вашего сервиса.
Полагаться на то, что event broker будет за вас реализовывать идемпотентность, нельзя. Иначе вы попадаете в неизбежный сбой: временная коммуникационная проблема с event broker превращается в перманентную проблему вида "мы забронировали билет, но не сформировали накладную и не выслали письмо клиенту с подтверждением бронирования". Теперь её решение потребует дорогостоящей сессии со службой поддержки и ручными корректировками состояния сервисов. Хорошо, если ваш сервис пережил время сбоя коммуникаций, и у вас достаточно длинный retry-цикл. А если так оказалось, что ваш сервис был принудительно перезапущен после коммита в БД, но до отправки event, то упс.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.