Я создаю инструмент мониторинга на Erlang. При запуске в кластере он должен запускать набор функций сбора данных на всех узлах и записывать эти данные с помощью RRD на одном узле «записывающего устройства».
В текущей версии на главном узле (rolf_node_sup
) работает супервизор, который пытается запустить второй супервизор на каждом узле кластера (rolf_service_sup
). Затем каждый из супервизоров на узле должен запустить и контролировать группу процессов, которые отправляют сообщения обратно на gen_server на главном узле (rolf_recorder
).
Это работает только локально. Ни на одном удаленном узле не запущен супервизор. Чтобы загрузить -узел-супервизор от узла регистратора:
rpc:call(Node, supervisor, start_child, [{global, rolf_node_sup}, [Services]])
Я нашел пару человек, предполагающих, что супервизоры на самом деле предназначены только для локальных процессов. Например.
Каков наиболее эффективный способ OTP для реализации моего требования иметь контролируемый код, работающий на всех узлах в кластере?
- Распределенное приложение предлагается в качестве альтернативы распределенному дереву супервизора. Это не подходит для моего варианта использования. Они обеспечивают переключение между узлами, но поддерживают выполнение кода на наборе узлов.
- Интересен модуль pool. Однако он обеспечивает выполнение задания на узле, который в настоящее время наименее загружен, а не на всех узлах.
- В качестве альтернативы я мог бы создать набор контролируемых «прокси-процессов» (по одному на узел) на главном сервере, которые используют
proc_lib:spawn_link
для запуска супервизора на каждом узле. Если что-то пойдет не так на узле, прокси-процесс должен умереть, а затем быть перезапущен его супервизором, который, в свою очередь, должен перезапустить удаленные процессы. Здесь может быть очень полезен модуль подчиненный. - Или, может быть, я слишком усложняю. Непосредственное наблюдение за узлами - плохая идея, вместо этого, возможно, мне следует спроектировать приложение для сбора данных более слабосвязанным способом. Создайте кластер, запустив приложение на нескольких узлах, скажите одному, чтобы он стал мастером, и оставьте все как есть!
Некоторые требования:
- Архитектура должна быть способна справляться с присоединением узлов к пулу и выходом из него без ручного вмешательства.
- Я хотел бы построить решение с одним мастером, по крайней мере на начальном этапе, для простоты.
- Я бы предпочел использовать существующие возможности OTP вместо ручного кода в моей реализации.