Всем привет. Задача следующая. Хочу понять можно ли вообще организовать такую схема, и какими средствами.
Есть несколько микросервисов, которые должны общаться между собой через кролика. Удобно было бы сделать в рамках одной очереди. Соответственно, для того что бы это можно было реализовать, нужно как то сделать что бы сообщение получал только тот подписчик, которому оно адресовано. Я курил в сторону хедеров сообщений, что бы сделать как то его уникальным, но результата так и не добился. Сообщение получает первый успевший его выхватить. А мне надо, что бы все слушатели оставались на связи, но сообщение доходило только до конкретного, кому адресовано. Как это сделать?
Для RabbitMQ все консьюмеры одной очереди считаются равноправными, вся маршрутизация выполняется до очереди, то есть каждый отдельный сервис (один консьюмер или их группа) должен иметь свою очередь.
Сложно давать совет не зная целей, но никто не мешает создать эксченджи типа BtoA, CtoA, DtoA, AtoB и т.д., для каждого "сервиса" создать одну очередь и подписать на несколько эксченджей, или несколько очередей - по одной на каждый. Но это выглядит очень странно на мой взгляд.
Илья, просто в моей архитектуре если у меня 10 микросервисов воркеров, и один центральный, то мне надо будет делать для каждого микросервиса отдельную очередь, а в корневом каждый раз дописывать новую очередь для прослушивания вручную, так как динамически это не сделаешь, а проект подразумевает рост микросервисов.
Павел Сахаров, понятно. Мне в голову приходит либо решение с избыточностью, когда делается широковещательная рассылка на все консьюмеры, а консьюмер откидывает все сообщения кроме своих. Но недостаток этого решения понятный - широковещательная рассылка. Либо использовать что-то что не rabbit.
Может прямое подключение сервисов в центр по tcp или что-то еще. А эти воркеры могут получать асинхронно сообщения?
Не совсем понимаю, что у вас за проблема с центральным сервисом, но что мешает каждому сервису дать имя/идентификатор, в том числе и центральному, создать обменники с такими же именами, подцепить соответствующие очереди и посылать сообщения в эти обменники? Это как месенджер, вы же не заводите отдельный аккаунт на каждого собеседника, просто при получении сообщения в нём есть некий идентификатор, по которому можно понять кто отправитель.
Сергей, Задача следующего плана. Каждый из воркеров делает запрос к центральному сервису. Тот делает дорогие логики и на выходе отдает ответ. Ответ должен быть доставлен только тому кто делал запрос. Помимо этого воркеры так же отдают логи без ожидания ответа центральному.
Сергей, При этом воркеры, это по сути идентификаторы клиентов. При подключении клиента, добавляется еще один воркер. Соответственно подключение воркера должно делаться динамически, и центральный должен уметь идентифицировать нового воркера. Если реализовывать путем добавления очередей, то встает вопрос кто первее курица или яйцо. Так как если центральному надо сделать массовую рассылку, то он должен знать список воркеров. Это все конечно можно сделать дополнительной системой хранения списка воркеров, но это избыточность, и не хотелось бы строить говноархитектуру
То есть хотите сделать RPC-вызов? Посмотрите на Direct Reply-to. Вот пример использования.
Если центральному для каких-то задач надо сделать бродкаст-рассылку, то сделайте fanout обменник и подписывайте очередь каждого клиента на этот обменник, затем просто отправляйте с центрального одно сообщение в этот обменник, дальше всё сделает RabbitMQ.
Если подробно объяснить весь флоу, то суть такая.
Есть динамическое число воркеров - агентов на разных нодах или виртуалках. Их задача анализ данных на лету на основе агрегированных данных у себя в памяти, а так же на основе ретроспективных данных. Для реализации ретроспективного анализа, воркеры отсылают к центральному пачки больших данных, которые, центральный агрегирует в базу clickhouse. Для ретроспективного анализа на лету, воркеры делают запрос к центральному, который должен дать ответ только тому кто запрашивал. Вот в целом и все.