Запретить несколько экземпляров NodeJS обработки события Redis PubSub - PullRequest
1 голос
/ 14 июля 2020

У меня интересная головоломка; Я использую шаблон Redis PubSub для генерации событий в моей сети из NodeJS микросервисов. Я отказался от RabbitMQ, потому что мне нужно, чтобы сообщения были многоадресными, чтобы несколько микросервисов могли получать и обрабатывать одно и то же событие. Поэтому, если я испущу событие LOGOUT, его должны услышать и UserService, и WebSocketService.

Это работало нормально до тех пор, пока мой клиент не развернулся в среде, в которой работает несколько экземпляров каждого микросервиса. Теперь, учитывая 3 экземпляра UserService, все экземпляры подключаются к Redis, и все они получают и обрабатывают событие LOGOUT, что плохо.

Итак, с одной стороны, мне нужны отдельные микросервисы, чтобы слышать событие, но на другой - мне нужно, чтобы дубликаты одного и того же микросервиса не обрабатывали событие. Рок, встречайте наковальню.

На данный момент я думаю, что это немного взломано, но что-то вроде:

  1. Вместо того, чтобы вызывать события, напишите в кэш Redis список событий
  2. UserService и WebSocketService могут читать этот список каждые 3 секунды и проверять наличие новых событий, требующих обработки.
  3. При обнаружении соответствующего события UserService добавит его «имя» в список служб. который обрабатывает событие
  4. Когда WebSocketService видит событие, он все равно сможет обработать его и добавить свое «имя» в список обработчиков.
  5. Когда дублирующийся экземпляр UserService видит событие , он увидит свое «имя» уже в списке обработчиков и проигнорирует это событие

Мне не нравится это решение, потому что список будет постоянно увеличиваться в памяти, а не во временном сообщении . Также мне придется начать добавлять код для управления тем, какие события уже были проверены; в противном случае в каждом цикле весь список должен был бы анализироваться заново всеми экземплярами всех сервисов.

Идеи приветствуются.

Ответы [ 4 ]

1 голос
/ 16 июля 2020

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

1 голос
/ 17 июля 2020

Потоки Redis кажутся полезными для вашего варианта использования. Вы это проверили?.

У нас может быть несколько групп потребителей. Как и pub / sub, ожидается, что каждая группа потребителей получит сообщение из потока. (Здесь поток выглядит как pub / sub channel / topi c). Однако, когда в группе потребителей есть несколько узлов, только один узел будет обрабатывать событие. Не все. Узел может подтвердить сообщение, которое он обработал.

  • После перезапуска узлы не будут обрабатывать уже доставленное сообщение
  • Поток будет продолжать расти. Мы можем обрезать по размеру. Мы можем сохранить последние элементы N.

введите описание изображения здесь

0 голосов
/ 17 июля 2020

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

  • В моем случае я использовал mongodb в качестве базы данных, поэтому всякий раз, когда я получал уведомление keySpace, я создавал запись -lock к моей базе данных для этой конкретной подписки.

Итак, я создал саму блокировку записи. Каждый раз, когда я получаю подписку на этот конкретный ключ, на который вы подписались, я увеличивал значение ключа относительно этот конкретный документ на 1. И при обновлении я получаю nModified: 1 в моем случае, когда он был изменен путем создания соответствующих условий.

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

Вы можете сделать то же самое, создав свою собственную блокировку записи.

Hail Coding

0 голосов
/ 14 июля 2020

После получения уведомления использовать список событий Redis, используя LPOP , и действовать только в том случае, если что-то действительно есть в этом списке.

Это одновременно очистит список событий и гарантирует, что только один потребитель фактически выполнит действие.

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