PUB / SUB с недолговечным издателем и долгоживущими подписчиками - PullRequest
7 голосов
/ 23 апреля 2011

Контекст: ОС: Linux (Ubuntu), язык: C (на самом деле Lua, но это не имеет значения).

Я бы предпочел решение на основе ZeroMQ,но приму что-нибудь достаточно вменяемое.

Примечание: по техническим причинам я не могу использовать здесь сигналы POSIX.

У меня есть несколько идентичных долгоживущих процессоводна машина («рабочие»).

Время от времени мне нужно доставлять управляющее сообщение каждому из процессов с помощью инструмента командной строки.Пример:

$ command-and-control worker-type run-collect-garbage

Каждый из рабочих на этом компьютере должен получить сообщение run-collect-garbage. Примечание: было бы идеально, если бы решение как-то работало для всех работников на всех машинах в кластере, но я могу написать эту часть самостоятельно.

Это легко сделать, если я буду хранитьнемного информации о работающих работниках.Например, храните PID для них в известном месте и откройте управляющий сокет домена Unix по известному пути с PID где-нибудь в нем.Или откройте сокет TCP и сохраните хост и порт где-нибудь.

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

Есть ли хороший способ сделать это в стиле PUB / SUB?То есть работники - это подписчики, инструмент управления и контроля - это издатель, и все, что они знают, это, так сказать, единый «URL-адрес канала», по которому можно получать сообщения.

Дополнительнотребования:

  • Сообщения на канал управления должны разбудить работников из цикла опроса (выбрать, что угодно).
  • Доставка сообщенийдолжно быть гарантировано, и оно должно достигать каждого работающего, который слушает.
  • Работник должен иметь возможность отслеживать сообщения без блокировки - в идеале с помощью цикла poll / select / любого упомянутого циклавыше.
  • В идеале рабочий процесс должен быть в некотором смысле «сервером» - он не должен беспокоиться о сохранении постоянных соединений с «канальным сервером» (если таковые имеются) и т. д. - или об этомдолжно быть сделано прозрачно на основе.

Ответы [ 4 ]

4 голосов
/ 17 мая 2011

Обычно для такого шаблона требуется прокси-сервер издателя, т. Е. Вы отправляете прокси-серверу, который немедленно принимает доставку, а затем надежно передает его конечным подписчикам.Руководство ZeroMQ охватывает несколько различных способов реализации этого.

http://zguide.zeromq.org/page:all

2 голосов
/ 28 июня 2011

Учитывая ваши требования, предложение Стива кажется самым простым: запустите демон, который прослушивает два известных сокета - рабочие подключаются к нему, а командный инструмент проталкивает его, который перераспределяет подключенным рабочим.

Вы могли бы сделать что-то сложное, что, вероятно, сработало бы, эффективно назначив одного из работников.Например, при запуске работники пытаются связать () сокет PUB ipc: // где-нибудь доступным, например, tmp.Тот, который выигрывает bind () второй IPC в качестве гнезда PULL и действует как устройство пересылки поверх своих обычных обязанностей, другие подключаются () к исходному IPC.Инструмент командной строки connect () подключается ко второму IPC и отправляет его сообщение.Существует риск того, что победитель умрет, оставив заблокированный файл.Вы можете определить это в инструменте командной строки, перепривязать, затем перевести в спящий режим (чтобы можно было установить соединения).Тем не менее, это все немного сложнее, я думаю, я бы пошел с прокси!

0 голосов
/ 29 апреля 2011

Использовать мультикаст PUB / SUB. Вам нужно убедиться, что опция pgm скомпилирована в ваш дистрибутив ZeroMQ (man 7 zmq_pgm).

0 голосов
/ 23 апреля 2011

Я думаю, что то, что вы описываете, хорошо бы соответствовало реализации gearmand / supervisord.

Gearman - отличный менеджер очередей задач, а супервизор позволит вам убедиться, что все процессы запущены. Он также основан на TCP, так что вы можете иметь клиентов / работников на разных машинах.

http://gearman.org/

http://supervisord.org/

Недавно я настроил что-то с несколькими узлами редуктора, связанными с несколькими рабочими, чтобы не было единой точки отказа

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

Redis имеет некоторые приятные и простые функции паба / саба, которые я еще не использовал, но звучит многообещающе.

...