Pull to refresh

Comments 25

Любая оркестрационная сага на более высоком уровне или хореографическая или монолит всего приложения.

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

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

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

Спасибо за статью. Мы в ЮMoney тоже выбрали подход с оркестрацией при проведении платежей. Кажется что в вашем подходе есть проблема с организацией внутренней логики - появляется много условий и логику процесса тяжело поддерживать. У нас обычный процесс состоит из десятков шагов с ветвлениями. Чтобы разработчику и аналитику было проще разобраться мы использовали конечный автомат с декларативным описанием шагов по которому мы строим диаграмму процесса. Для компенсационных действий используется "обратный" автомат.

Можете, пожалуйста, пояснить - в чем проблема с логикой?

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

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

т.е. вы по-сути изобрели BPMN (ну или иной общеизвестный) язык описания процессов?

И наверное любое взаимодействие систем можно описать в терминах конечных автоматов.

Конечные автоматы все-таки сложно программировать, особенно когда там сложные циклы внутри, я потому и перешел сначала на акторы, а потом на workflow.
Ну а в Озоне, подозреваю, еще в самом начале пути )

забыл добавить (из ченжлога к 2.0.0), чтобы в полной мере оценить функционал этой реализации

Introduced new behavior gen.Saga. It implements Saga design pattern - a sequence of transactions that updates each service state and publishes the result (or cancels the transaction or triggers the next transaction step). gen.Saga also provides a feature of interim results (can be used as transaction progress or as a part of pipeline processing), time deadline (to limit transaction lifespan), two-phase commit (to make distributed transaction atomic).

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

А какой паттерн - Ваш выбор?

Честно говоря, не знаю)

Я заметил, что, похоже, у нас внутри не используют ни cadence, ни temporal.

Может быть дело было в неосведомленности.
Но могут быть и трудности интеграции с инфраструктурой. Дело в том, что у нас используется внутренний фреймворк, который реализует паттерн "Микросервисные шасси" - https://microservices.io/patterns/microservice-chassis.html . Он решает многие вопросы интеграции инфраструктуры. Возможно, запуск стороннего сервиса может потребовать доработки напильником.

Как бы там ни было, спасибо за наводку!
Решение выглядит интересным, особенно если нет каких-то инфраструктурных ограничений

Ну, даже если не тащить temporal, то можно было бы сделать свое решение в духе temporal.io, там идеология (не реализация) гораздо удобнее классических саг.
Ну или вообще сделать оркестратор как библиотеку, в стиле Haydn4k. Впрочем, не факт, что на go вообще можно написать удобный оркестратор.

Кстати, а какие требования у вас по производительности оркестраций? И по взаимодействию разных сценариев? И не совсем понятно, что происходит при падении воркера, как можно понять, что нужно повторить какие-то операции?

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

  2. По взаимодействию разных сценариев - если честно, не очень понял вопрос(

  3. Если воркер саг завис в промежуточном состоянии, то зависшие саги "отпустит" другой воркер. Об этом я писал выше в разделе "Обработка ошибок зависших воркеров". Все выполненные шаги хранятся как раз в саге.

Кстати, по поводу workflow. Если я правильно понимаю, то мы как раз и сделали нечто подобное temporal, только без сторонней библиотеки. Разве не так?

  1. Я скорее про число шагов, которое нужно выполнить в секунду, про скорость восстановления после падения воркера, про число одновременных процессов и т.п. Это те НФТ, которые больше всего влияют на подобные решения.

  2. Когда из одного сценария (саги) нужно вызвать другую, а потом продолжить работу. Частый сценарий, который через простую последовательность шагов уже не реализуется.

  3. Я не понял, как и когда другие воркеры поймут, что конкретные саги "зависли". Только по таймеру?

Насколько я понимаю, нет, ваше решение еще очень далеко от temporal. У вас поддерживается только линейная фиксированная последовательность шагов, а не любые сценарии; нет никакой поддержки версионирования сценариев; нет user-actions; весь ресайленс нужно реализовывать практически вручную; да и вообще, фактически, все нужно делать вручную, нет какого-то удобного фреймворка.

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

Потому и говорю, что вы еще в начале большого пути )

  1. Требований нет. Универсальный критерий - количество обращений в поддержку. Пока нам не жалуются на кейсы, связанные с регистрацией, мы считаем, что все ок.

  2. Если речь о том, чтобы дождаться другой саги, то да - это уже более сложный кейс. Я согласен с тем, что описанный выше подход не очень хорошо ложится на него.

  3. Да, только по таймеру

Кстати, а в Озоне разве нет общего стандартного решения для оркестрации? Вроде бы микросервисы у вас давно уже?

Либо такого пока еще нет, либо я о нем просто не осведомлен

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

Спасибо за статью (хабр ещё торт)! Теперь благодаря новой системе кармы могу выразить благодарность не только с помощью комментария ;)

Сейчас изучаю микросервисы и данная статья оказалась весьма кстати.

Спасибо.

  1. Блокируем пачку регистраций, используя SELECT FOR UPDATE.

  2. Сразу помечаем эти регистрации как обработанные.

Здесь похоже опечатка, судя по коду регистрации помечаются как обрабатываемые (PROCESSING), а не обработанные.

Действительно. Исправил, спасибо!

Sign up to leave a comment.