ERLANG分布式

ERLANG分布式系统

ERLANG分布式系统中包含一些可以相互连接、通信的ERLANG运行时系统,其中每个运行时系统都称为分布式系统中的节点。当使用PID进行不同节点的进程之间传递消息、链接和监视时,这些都是透明的操作。但是,已注册的名称是每个节点的本地名称。在使用注册名称发送消息等操作时也必须指定节点。

ERLANG分布式系统是基于TCP/IP实现的。具体实现描述,参见ERTS用户手册

警告

启动分布式节点时没有指定-proto_dist inet_tls的话,节点将会暴露给攻击者,攻击者可能会得到节点或整个集群的完全访问权限。在使用非安全的分布式节点时,必须确保主机网络配置的安全以防止潜在的攻击。如何设置安全的分布式节点,请参考Using SSL for Erlang Distribution

节点

分布式中的节点都是正在运行的ERLANG运行时系统,可以在启动时在命令行中使用-name或者-sname标志(参数)指定该节点的名称。

节点名称的格式是类似name@host的原子。其中name 是用户给节点的定义的名称。如果使用长名称,host将是完整的主机名称;如果使用短名称,host将是主机名字符中的第一部分。 node()函数调用将返回执行该调用的节点名称。

示例

% erl -name dilbert
(dilbert@uab.ericsson.se)1> node().
'dilbert@uab.ericsson.se'

% erl -sname dilbert
(dilbert@uab)1> node().
dilbert@uab

注意

使用长名称的节点不能连接到使用短名称的节点。

节点连接

默认情况下,ERLANG分布式系统中的节点是没有互相连接的。直到调用 Node,M,F,A)net_adm:ping(Node)等需要与其他节点通信的函数时,执行这些函数调用的节点才会试图去连接到其他节点(Node)。

默认情况下,节点的连接是可传递的。比如,如果节点A连接到节点B,节点B连接到节点C,那么节点A同样也会去尝试连接到节点C。这个特性可以在命令行中使用-connect_all false关闭,参见erl(1)

如果节点因各种情况关闭时,连接到该节点的所有连接将被移除。可以调用函数 erlang:disconnect_node(Node)来强制端口节点之间的连接。

调用函数nodes()可返回与当前节点相互连接的(可见)节点列表。

EPMD

ERLANG中负责端口映射管理的守护进程将在任意主机启动ERLANG节点时自动启动。它负责管理着代表节点的名称和主机地址之间的映射关系。参见epmd(1)

隐藏节点

在ERLANG分布式系统中,有时会想要连接到某节点,但不与分布式系统中的其他节点相连接。比如,有时我们仅需要连接到某节点上去检查系统状态,而不想要与分布式系统中的其他节点相连接。这样的情况,可以使用隐藏节点做到。

隐藏节点是节点启动时命令行中带有-hidden标志(参数)的节点。隐藏节点和其他节点之间的连接是不可传递的。它们之间必须要明确的指定所要连接的节点。同样,隐藏节点不会出现在nodes()函数的返回值列表中。这就是说隐藏的节点未添加到全局保持跟踪的节点集合中。

这个特性是在ERLANG 5.0/OTP R7版本时添加到系统中的。

C 节点

C节点就是C语言编写的,在ERLANG分布式系统中当作隐藏节点的节点, Erl_Interface函数库对此提供支持。更多关于C节点的信息,请参考Erl_Interface应用和Interoperability Tutorial

安全

在ERLANG分布式系统中的认证即是确定允许哪些节点与其他节点之间进行通信。在不同的ERLANG节点网络中,认证机制是在底层内置在系统中的。每个节点都有各自的COOKIE,它是ERLANG中的原子类型。

当节点尝试连接到其他节点时,将会对比双方的COOKIE是否一致。如果不一致,被动连接的节点将拒绝该节点的连接。

在启动时,节点将得到一个随机的原子假设为它的COOKIE,并且假设其他节点的 COOKIE是nocookie

ERLANG网络认证服务的第一个动作是去读取文件,如果该文件不存在,将会去创建该文件。该文件的UNIX权限模式将设置为八进制 400(属主只读模式),并且向该文件中写入随机字符串。所写入的随机字符串将通过eralng:set_cookie(node(), Cookie)函数设置为本地节点的COOKIE。这也使本地节点将假设所有其他节点也使用同样的COOKIE。

因此,具有相同COOKIE文件的用户组将可以不受COOKIE系统的干扰而自由的通信。想要在不同文件系统上运行ERLANG节点时必须确保所在文件系统中的COOKIE文件是相同的。

当节点一和节点二具有不同的COOKIE时,必须先调用函数 erlang:set_cookie(Node, Cookie)将两个节点的COOKIE设置为相同的原子之后,两个节点才可以相互连接。Distributed systems with multiple user IDs can be handled in this way.

默认情况下,在两个节点之间建立连接时,将立即连接所有其他可见节点。所以,这里始终是一个完全连接的网络。如果有节点使用了不同的COOKIE,这种方式将不再适用。这时必须设置命令行参数,参见erl(1)

可以通过函数erlang:get_cookie()获取本地节点的COOKIE。

分布式相关BIF

分布式程序设计中有关的BIF函数(更多信息,请参考erlang(3)

BIF 描述
erlang:disconnect_node(Node) 强制端口节点连接
erlang:get_cookie() 返回当前节点的Cookie
is_alive() 如果运行时系统是一个节点,并且可以连接到其他节点,此时返回true;否则返回false
monitor_node(Node, true false) 监视节点状态,当失去节点连接时,将会收到消息:{nodedown, Node}
node() 返回当前节点名称,允许在关卡中使用
node(Arg) 返回参数Arg所表示的pid、reference、port所在的节点
nodes() 返回所有可见并可连接节点列表
nodes(Arg) 依赖于函数调用时的参数,该函数可以返回不止是可见节点的列表,包括隐藏节点和函数调用前已知的节点,等等
erlang:set_cookie(Node, Cookie) 用于在连接节点时设置COOKIE,如果Node是当前节点,当连接到其他所有新的节点时,所设置的COOKIE将生效。(不影响函数调用之前的节点连接)
spawn[_link/_opt](Node, Fun) 在远程节点上创建进程
spawn[_link/opt](Node, Module, FunctionName, Args) 在远程节点上创建进程

分布式相关命令行标志(参数)

分布式程序设计中相关的命令行标志(参数)(更多信息,请参考erl(1)):

命令行标志 描述
-connect_all false Only explicit connection set-ups are used.
-hidden 将节点设置为隐藏节点
-name Name 使运行时系统为分布式节点,使用长名称
-setcookie Cookie 与调用函数eralng:set_cookie(node(), Cookie))一样的作用
-sname 使运行时系统为分布式节点,使用短名称

分布式相关模块

分布式程序设计中相关的模块

在KERNEL应用中:

模块 描述
global 全局名称注册中心
global_group 将节点分组到全局名称注册组
net_adm 包含ERLANG网络管理操作函数
net_kernel ERLANG网络核心

在STDLIB应用中:

模块 描述
slave 包含启动和控制从节点的函数

Date: 2018-08-06 Mon 14:33

Author: xshumeng

Email: xue.shumeng@yahoo.com

Created: 2023-08-28 Mon 14:16