Слоение очередей

Обсуждаем, как правильно строить приложения
Ответить
nootropil
Сообщения: 46
Зарегистрирован: 2015.11.21, 18:45

Слоение очередей

Сообщение nootropil »

Доброго времени суток.

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

Думаю что это не должно быть в доменном слое, но вот не уверен слой ли это приложения или инфраструктуры.

Пример с отправкой email'ов:

https://bitbucket.org/nootropil/studyin ... er.php-165

https://bitbucket.org/nootropil/studyin ... ler.php-66

https://bitbucket.org/nootropil/studyin ... ?at=master


Любая адекватная критика как по архитектуре так и по реализации работы с очередями приветствуется.
glagola
Сообщения: 47
Зарегистрирован: 2017.02.22, 19:43

Re: Слоение очередей

Сообщение glagola »

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

Что касается транзакционности - у меня по факту 2 EventPublisher'a, через которых можно подписаться на события:
  • Доменный (моментальная реакция подписчиков на публикуемое событие в рамках одной транзакции)
  • Инфраструктурный (агрегирует все доменные события, произошедшие в рамках транзакции, и по ее успешному завершению начинает скармливать их своим подписчикам)
Таким образом если я хочу отправить Email - то просто подписываюсь на событие UserPasswordReset в инфрастурном EventPublisher'e, дальше подписчик генерирует задание и кидает его в очередь.

P.S. не претендую на правильность решения/терминологии - пока такая связка работает :)
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Слоение очередей

Сообщение zelenin »

я делаю через шину событий, один exchange и topic'и. Консьюмеры могут подписываться на топики и получать свои события.

https://bitbucket.org/nootropil/studyin ... er.php-165
зачем разделены выполнение команды и генерация события по его результатам? это должно быть в хэндлере.

В целом в коде все намешано и перепутано местами. Рекомендую такой подход:

Event - обычный объект (PostCreated, UserRegistered итд)
EventBus - шина с методом handle, принимающим объект события. Внутри RabbitMqConnection, посылающий RabbitMqEvent в шину.
RabbitMqConnection работает с одним эксченджем типа topic.
RabbitMqEvent - простой объект, состоящий из payload (непосредственно Event), type (короткое имя класса, типа PostCreated), topic (неймспейс объекта, нормализованный до имени топика - module.domain.blog.event.post_created - позволит удобно подписываться на нужные топики типа module.domain.blog.*)
Событие сериализуется Serializer'ом. В моем случае это ObjectDeepSerializer, который с помощью hydrator рекурсивно нормализует объект до массивов ['class' => '...', 'payload' => '...'], а потом восстанавливает обратно. Так сделано для отсутствия связанности между различными частями приложения. Если связанность не пугает, то можно реализовывать интерфейс JsonSerializable.
Консьюмеры подписываются на топики.


https://github.com/zelenin/message-bus - шина с поддержкой middleware с контекстом, передаваемого через весь стек мидлварей, с помощью которого можно пробрасывать результаты выполнения хэндлеров или мидлварей (например вернуть ошибки валидации или свежесозданные объект). Из коробки HandlerMiddleware, который позволит обрабатывать события в рамках запроса. Ручками можно дописать RabbitMqMiddleware, который будет хэндлить все события и кидать в rabbit.
https://github.com/zelenin/hydrator - гидратор для извлечения данных из объекта и создания объекта на основе извлеченных данных.
Serializer пока не релизил.
sda
Сообщения: 334
Зарегистрирован: 2013.12.19, 09:29

Re: Слоение очередей

Сообщение sda »

glagola, а как соблюдается консистентность и дедупликация событий?
nootropil
Сообщения: 46
Зарегистрирован: 2015.11.21, 18:45

Re: Слоение очередей

Сообщение nootropil »

Спасибо за ответы.
zelenin писал(а): 2017.06.11, 15:14 я делаю через шину событий, один exchange и topic'и. Консьюмеры могут подписываться на топики и получать свои события ...
Интересный вариант. Попробовал реализовать близко к тому, что вы предложили.

https://bitbucket.org/nootropil/studyin ... er.php-111

https://bitbucket.org/nootropil/studyin ... ler.php-63

https://bitbucket.org/nootropil/studyin ... ew-default

https://bitbucket.org/nootropil/studyin ... ler.php-73


Могли бы вы прокомментировать на сколько правильно я вас понял?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Слоение очередей

Сообщение zelenin »

да, похоже. только тут:
https://bitbucket.org/nootropil/studyin ... ew-default
я бы две разных мидлвари использовал - одну, ту, что из коробки - для хэндлеров, вторую самописную для rabbit, которая бы только в рэббит отсылала.
Ответить