我正在Erlang 中构建一个监控工具。在集群上运行时,它应该在所有节点上运行一组数据收集功能,并使用 RRD 在单个“记录器”节点上记录该数据。
当前版本在主节点 ( rolf_node_sup
) 上运行一个主管,它尝试在集群中的每个节点 ( ) 上运行第二个主管rolf_service_sup
。然后,每个节点上的监督者应该启动并监视一堆进程,这些进程将消息发送回主节点上的 gen_server ( rolf_recorder
)。
这仅在本地有效。没有在任何远程节点上启动主管。我使用以下代码尝试从记录器节点加载节点上的主管:
rpc:call(Node, supervisor, start_child, [{global, rolf_node_sup}, [Services]])
我发现有几个人建议主管真的只为本地流程设计。例如
实现我要求在集群中的所有节点上运行监督代码的最 OTP 方式是什么?
- 建议将分布式应用程序作为分布式主管树的一种替代方案。这些不适合我的用例。它们提供节点之间的故障转移,但保持代码在一组节点上运行。
- 池模块很有趣。但是,它允许在当前负载最少的节点上运行作业,而不是在所有节点上运行。
- 或者,我可以在主节点上创建一组受监督的“代理”进程(每个节点一个),用于
proc_lib:spawn_link
在每个节点上启动一个监督者。如果节点上出现问题,代理进程应该死掉,然后由它的主管重新启动,这反过来又应该重新启动远程进程。从模块在这里可能非常有用。 - 或者,也许我过于复杂了。直接监督节点是一个坏主意,相反,也许我应该构建应用程序以更松散耦合的方式收集数据。通过在多个节点上运行应用程序来构建一个集群,告诉一个成为主节点,就这样吧!
一些要求:
- 该架构应该能够处理节点加入和离开池而无需人工干预。
- 为了简单起见,我想构建一个单主解决方案,至少最初是这样。
- 在我的实现中,我更愿意使用现有的 OTP 工具而不是手动代码。