【问题标题】:Will network interruption trigger monitor_node or link broken in Erlang/Elixir?网络中断会在 Erlang/Elixir 中触发 monitor_node 或链接断开吗?
【发布时间】:2019-04-21 07:24:57
【问题描述】:

在分布式情况下,例如运行在不同机器上的 3 个节点,它们在 Erlang/Elixir 中默认连接为 clique。我们称它们为 A、B 和 C(它们通过调用 network:connect 显式连接)。假设 A 和 B 之间发生网络中断。

1) A 和 B 之间的中断是否会触发 A 和 B 上的进程之间的链接断开 (spawn_link),因为我们仍然有 C 作为中间连接节点。那么 monitor_node (将在 A 或 B 上触发)呢?

2) 由于 C 作为中间连接节点,我们还能从 A 的进程向 B 的进程发送消息吗?

3) Erlang/Elixir 的成员资格组件如何解决这种情况?连接是否会恢复,毕竟没有什么不好的事情发生(没有链接断开,没有返回 monitor_node 消息,就像一切都立即恢复一样)?

感谢您对这个问题的任何考虑!

【问题讨论】:

    标签: erlang elixir erlang-otp


    【解决方案1】:

    1) A 和 B 之间的中断是否会触发 A 和 B 上的进程之间的链接断开 (spawn_link),因为我们仍然有 C 作为中间连接节点。 monitor_node 呢(会在 A 或 B 上触发)?

    Erlang节点的默认行为是连接传递,意思是当connectping之类的函数从节点A调用到B时,如果连接建立,A也会尝试连接到B已知的所有节点,即在节点B调用nodes()时得到的列表。

    2) 我们还能从 A 的进程向 B 的进程发送消息吗? C作为中间连接节点?

    这取决于,如果 A 能够使用我上面提到的传递行为直接连接到 B,那么它没有任何区别。见下文:

    A ----- C ----- B

    如果您将 A 连接到 C 并将 C 连接到 B,这就是您想象节点之间的链接的方式。但实际上它看起来像这样:

    A ----- C
    \     /
     \   /
       B
    

    所以即使节点 C 正在运行,A 也不会通过它到达 B。但是如果通过 C 是 A 到达 B 的唯一物理方式,那么 A 和 B 将无法再进行通信.

    3) Erlang/Elixir 的成员资格组件是如何解决这个问题的 情况?连接会恢复吗?真的没什么不好 毕竟发生了(没有链接中断,没有返回 monitor_node 消息 就像一切都立即恢复一样)?

    如果被监控的节点宕机,会有{nodedown, Node}形式的消息发送给监控进程,以便它可以处理故障。除非节点本身恢复,否则连接不会恢复。例如,如果故障节点在网络中不扮演关键角色,并且其他节点仍然可以相互通信,那么您可以说真的没有什么不好的事情发生

    但在我看来,这是一种非常鲁莽的方式来查看节点故障,即使 Erlang 被认为是容错的,也不应将其视为故障接受,即应该始终处理错误.

    希望这会有所帮助:)

    【讨论】:

    • 那么 Erlang 中的节点是否只有其有向连接邻居的拓扑知识?由于它是默认的 clique 拓扑,如果发生网络中断,是否有任何节点只是假定邻居已关闭(无论它是否间接连接)?
    • 我认为拓扑中没有方向的概念。默认情况下,每个连接都是双向的。 nodes() 函数将返回当前节点连接的节点列表。如果一个节点因为不再存在到它的路径而变得无法访问,它将不再出现在nodes() 列表中。
    【解决方案2】:

    1) A和B之间的中断是否会触发联动中断 (spawn_link) 在 A 和 B 上的进程之间,因为我们仍然有 C 作为 中间连接节点。 monitor_node 呢(会在 A 或 B 上触发)?

    2) 我们还能将消息从 A 的进程发送到 B 的进程吗 因为 C 作为中间连接节点工作?

    Erlang 有一个名为epmd(Erlang Port Mapper Daemon) 的服务,它将节点的信息(ip,名称)广播到其他节点,这些节点将保存它们。 这意味着,每个节点都有一个关于其他节点的信息图。 所以如果网络中断能够恢复并且节点没有死掉(重启),节点就可以正常通信了。 以上的情况可以。现在说说不能交流的情况,就是epmd(Erlang Port Mapper Daemon)down。此时,旧节点会保存彼此的信息,以便它们可以互相调用。重启epmd后,现在创建的新节点不能调用旧节点,因为旧节点没有广泛的信息。

    3) Erlang/Elixir 的成员资格组件是如何解决这个问题的 情况?连接会恢复吗?真的没什么不好 毕竟发生了(没有链接中断,没有返回 monitor_node 消息 就像一切都立即恢复一样)?

    如果与monitor_node 的连接丢失,monitor_node 将收到一条消息{nodedown, Node}spawn_link 只是链接两个进程,只能接收process down msg

    【讨论】:

    • “旧节点”与“新节点”是什么意思?
    • 那么,即使B还活着,如果A monitor_node B,连接丢失后会收到{nodedown, B}? (注意:我们有 C 仍然连接到 A 和 B)
    • @chenyuandong 1. A, B create 2. epmd down 并重新启动 3. C, D created : A 和 B 是旧节点,C 和 D 是新节点。
    • @chenyuandong 是的。 A 将收到{nodedown, B} 。 > 如果与它的连接丢失,monitor_node 将收到一条消息 {nodedown, Node}。
    猜你喜欢
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多