Как организовать отправку сообщений в множество микросервисных нод?
Есть самонописанная сетевая нода (микросервис) на golang. Она принимает текстовые сообщения через REST и далее требуется отправить это сообщение другим таким же нодам (список нод заранее известен, их может быть 1, 30, 100 и т.д. любое количество). Но, ноды между сообой пересылают сообщения через grpc. Т.е. у каждой ноды две точки приема сообщений - rest и grpc. Как организовать передачу таких сообщений с точки зрения архитектуры? Складывать сообщения от rest и grpc в общую очередь и другим потоком делать отправку, наверное будет не очень эффективно. Разгребать общую очередь пулом потоков не очень понятно как, т.к. придется как-то делить сообщения по потокам в пуле и отправляемым другим адресам нод, но все ноды должны получить каждое сообщение. Отправлять без очереди, сразу при поступлении новых сообщений - накладные расходы на установку grpc-соединений. По сути каждое новое сообщение будет инициировать новое клиентское подключение к серверу и создавать новую горутину, что приведет к задержкам в сети, выделению лишней памяти и т.п.
Какие есть подходы для решения такой проблемы?
Когда сообщение приходит в сервис, его надо отправить на одну любую из 30-100 нод другого сервиса? Или же надо, чтобы каждая из этих 30-100 нод другого сервиса получила сообщение?
nelfo, Если хочется обойтись без очередей, тогда на ноде-сервере делаете grpc-стрим и все клиенты туда подключаются. Внутри придется реализовать ту же самую очередь, что сделана в Кафке.
Александр Павлюк, да, думаю в этом направлении. Осталось придумать, как разбирать эту очередь, одним потоком или несколькими и как организовать отправку сообщений - в цикле по каждому серверу или на каждый поток в отдельной гопутине. А то может оказаться, что начнется генерация огромного количества горутин, если сообщения начнут приходить в большом количестве.
Берете какой-нибудь брокер сообщений.
Например, Rabbitmq.
Там создаёте exchange с типом fanout. Туда будете слать сообщения из сервиса-отправителя.
Каждый сервис-получатель будет подключаться к этому exchange и для каждого будет создаваться своя очередь, куда будут попадать все сообщения. И каждый сервис спокойно сам вычитает свою очередь. И даже если он упадёт, то дочитает их после того, как подымется. https://youtu.be/P_EtQ-s-hiU?si=tavSDSzTnGpqQrAY
nelfo, Ну так если кидать всем GRPC-запросы, то центральным звеном тут будет сервис-отправитель. И там должен быть список тех, кому но должен отправлять запросы. Если какой-то из сервисов-приемников ляжет в момент запроса, то на отправителе надо будет предусматривать такую ситуацию.
Где-то вам всё равно надо держать список нод. Это всё равно будет центром, как ни крути.
Поэтому, очередь выглядит более здравой идей.
Если у тебя будет 100 нод-получателей то полюбому хотя-бы одна из них будет недоступна в момент отправки.
Такова природа вещей. И не стоит требовать от сетей перфекционизма. Сети работают как погода. Как дождь
или снег. Надо это учитывать.
Поэтому брокер сообщений на базе Kafka или Apache Pulsar или Rabbit будет вполне себе реальным решением.
Ты пишешь про p2p. Но какой ценой этот p2p ты собираешся поддержать на продюсере? Ты создашь 100 сокетов
и 100 буферов отправки сообщений?
Потому что другого выхода у тебя на самом деле нет. Или у тебя просто не пройдет транзакция я гарантирую
это.