Pull to refresh

Comments 17

Рассматривали ли вы уже существующие способы реализовать scheduled delivery? Например:
RabbitMQ Delayed Message Plugin — имеет сложности с обслуживанием сотен и миллионов сообщений. Нет удаления сообщений. Указывается задержка перед отправкой, что может привести к смещению времени выполнения, например, если возникнет какая-нибудь задержка в цепочке вызовов от клиентского сервиса.

ActiveMQ Delay and Schedule Message Delivery — Указывается задержка перед отправкой, не UTC метка. Похоже, так же нет удаления.

Amazon SQS message timers — как Вы сами сказали, есть ограничения, 15 мин максимум.

Среди указанных тут, Kafka Message Scheduler и Azure Service Bus… имеют очень похожий функционал на Trigger Hook. Создание с меткой UTC, возможность удаления.
Trigger Hook хранит свое состояние в оперативной памяти.

Каким образом реализована отказоустойчивость сервиса? Что произойдет если на любом этапе выполнения задачи один из контейнеров будет потерян? Выглядит как очередной велосипед и переизобретение условной celery (при этом у celery апи гораздо удобнее).

При потере контейнера, все предзагруженные задачи при этом останутся в MySQL. Когда будет создан новый контейнер, его состояние восстановится из базы. Ничего не потеряется.
Чем не устраивает просто писать consumer'ов для rabbitmq queue? с установленным delayed message plugin, например? это если в сторону простоты

а если в сторону универсальности, то delayed task это часть workflow, например в рамках BPMN. И соответственно, вероятно, проще весь workflow выполнять на каком-то движке, не выделяя отдельно delayed task. Пробовали ли какой-то workflow engine (https://github.com/meirwah/awesome-workflow-engines) для решения своей задачи по отложенным рассылкам?

Чем не устраивает просто писать consumer'ов для rabbitmq queue? с установленным delayed message plugin, например? это если в сторону простоты

Как уже отвечал выше, RabbitMQ Delayed Message Plugin имеет сложности с обслуживанием сотен и миллионов сообщений. Нет удаления сообщений. Указывается задержка перед отправкой, что может привести к смещению времени выполнения, например, если возникнет какая-нибудь задержка в цепочке вызовов от клиентского сервиса.

Такая задача кстати решается на cadence/temporal. На уровне каждого воркфлоу можно делать сколько угодно таймеров.

Анимация прикольная.

А можно пример необходимости команды на удаление задач из вне? Т.е. по идее можно в task положить данные по актуальности задачи и на уровне исполнения при наступлении времени отсеять как более не актуальную, не так ли?

Т.е. по идее можно в task положить данные по актуальности задачи и на уровне исполнения при наступлении времени отсеять как более не актуальную, не так ли?

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

А можно пример необходимости команды на удаление задач из вне

Например, я подписался на некую услугу — в итоге создалась задача на списание суммы со счета через месяц. Но через какое-то время передумал, отменил подписку — отложенная задача удалилась.

Разница — обработать сейчас эту задачу удалив ее. Или же дождаться выполнения задачи и во время выполнения отменить ее, выяснив дополнительные условия.

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

Не нравится мне что у этой службы своя СУБД. Понимаю что микросервисы и всё такое, но вот в чём я вижу проблему:


Для того, чтобы создать задачу — надо отправить сообщение. Сообщение может потеряться. Даже при использовании MQ с гарантированной доставкой сообщение может не дойти до MQ (скажем, брокер упал и ещё не перезапустился). Значит, для отправки сообщения нужно делать повторные попытки. Вот только повторные попытки — это тоже отложенная задача, которую как раз бы и хотелось переложить на Trigger Hook.

Для того, чтобы создать задачу — надо отправить сообщение. Сообщение может потеряться. Даже при использовании MQ с гарантированной доставкой сообщение может не дойти до MQ (скажем, брокер упал и ещё не перезапустился). Значит, для отправки сообщения нужно делать повторные попытки. Вот только повторные попытки — это тоже отложенная задача, которую как раз бы и хотелось переложить на Trigger Hook.


Trigger Hook больше заточен для работы на уровне бизнес процессов:
  • задачи с любым временем задержки — 0 сек или нескольких лет.
  • стремление к максимально точному времени запуска задач
  • механизмы для предотвращения потерь задач (на это, в числе прочего, работает реляционная база)


Для задачи повторных попыток запросов:
  • не очень подходит «назначение даты следующей попытки запроса». Тут больше подойдет подход именно с задержкой перед повторной попыткой запроса. Важен интервал между попытками, а не точная дата запуска.
  • в общем случае, не особо важно, если одна из попыток запроса где-то «затеряется». Например, делается повторная попытка каждую секунду, но, допустим, третья попытка не выполнилась — не страшно, так как через секунду выполнится очередная. Если Вы можете допустить в вашем приложение подобное — скорее всего, Trigger Hook излишне сложное решение.
  • в общем случае, так же, не нужна возможность установки задач на повторные попытки запросов на очень длительное время


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

В случае падения брокера Ваше приложения будет полностью парализовано (если это основной транспорт). Тут наверное стоит делать реплику для повышения доступности.

Не нравится мне что у этой службы своя СУБД

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

PS. ответ пользователю mayorovp

Объединение двух СУБД вместе само по себе не сделает им общие транзакции.

Если и есть смысл переносить все в одну СУБД, то что бы не выделять отдельный ресурс. Схемы при этом необходимо держать отдельно — для микро-сервисов это принципиальный момент.

Даже если получится использовать одну схему базы данных для нескольких микро-сервисов — то это гарантированно приведет к усложнению поддержки, это будет адом. Если несколько микро-сервисов используют одну схему базы данных совместно — то это уже не микро-сервисная архитектура (возможно, это распределенный монолит) и это выходит за рамки статьи.
в принципе всё делается без лишних звеньев на kafka + kafka stream + ksql
Sign up to leave a comment.

Articles