ZeroMQ Pub-Sub + Динамическое обнаружение без посредника

Я тестирую ZeroMQ как Pub-Sub (стиль служебной шины) для средней системы. У нас около 50 узлов, все они должны быть издателями и подписчиками. Сеть похожа на звездную топологию, но края "разговаривают" друг с другом. Нам требуется динамическое обнаружение (нет необходимости жестко программировать сетевые адреса участников), но также нет SPOF (Single Point of Failure).

Я прочитал http://zeromq.org/whitepapers:0mq-3-0-pubsub и, насколько я понимаю, предлагаемый способ для динамического обнаружения 0MQ включает прокси node (XPUB/XSUB), который пересылает подписки и публикации. Я рассматривал использование такого прокси-сервера как центрального посредника в нашей системе, однако у меня есть следующие проблемы с этой архитектурой: (A) Прокси node является SPOF - когда он терпит неудачу, вся система не работает (B) Весь трафик, включая данные, проходит через прокси node, что означает проблему с задержкой и производительностью.

Предполагая, что я правильно понял технический документ pub-sub, существует ли относительно простой способ достижения pub-sub + dynamic-discovery + no-SPOF в ZeroMQ?

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

Ответ 1

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

Вы можете развернуть несколько прокси-серверов XSUB/XPUB, каждый на своей машине, а затем развернуть балансировщик нагрузки (например, F5) между издателями и прокси-серверами. Это обеспечивает балансировку нагрузки и отказоустойчивость на стороне выше по течению.

Прокси-код прост:

Socket frontend = context.socket(ZMQ.XSUB);
frontend.bind("tcp://proxy1:5444");
Socket backend = context.socket(ZMQ.XPUB);
backend.bind("tcp://proxy1:5555");
frontend.subscribe("".getBytes());
ZMQ.proxy (frontend, backend, null);

Если прокси-сервер node не работает, просто перезапустите его; re-connections/subscriptions следует обрабатывать автоматически zmq.

Для нисходящих подписчиков подключите каждого абонента непосредственно ко всем доступным прокси:

subscriber = ctx.createSocket(ZMQ.SUB)
subscriber.connect( "tcp://proxy1:5555")
subscriber.connect( "tcp://proxy2:5555")
subscriber.connect( "tcp://proxy3:5555")

Издатели приходят и уходят чаще, чем прокси, поэтому подключение подписчиков непосредственно к прокси приводит к меньшему обслуживанию конфигурации, поскольку количество прокси-серверов будет, по большей части, статическим.

Если прокси-сервер node терпит неудачу, верхние LTM-маршруты трассируют трафик соответственно остальным прокси-узлам; абоненты не будут затронуты, так как они потребляют все доступные прокси.

Медленный абонент может быть отправлен с синхронизацией, прочитайте this.
Откроем подписку на forwading и минимизируем сетевой трафик здесь.

enter image description here