查看源代码 net_kernel (kernel v10.2)

Erlang 网络内核。

网络内核是一个系统进程,注册为 net_kernel,它必须运行才能使分布式 Erlang 工作。此进程的目的是实现 BIFs spawn/4spawn_link/4 的一部分,并提供对网络的监控。

Erlang 节点使用命令行标志 -name-sname 启动

$ erl -sname foobar

也可以直接从正常的 Erlang shell 提示符调用 net_kernel:start(foobar, #{})

1> net_kernel:start(foobar, #{name_domain => shortnames}).
{ok,<0.64.0>}
(foobar@gringotts)2>

如果节点使用命令行标志 -sname 启动,则节点名称为 foobar@Host,其中 Host 是主机的简称(不是完全限定域名)。如果使用标志 -name 启动,则节点名称为 foobar@Host,其中 Host 是完全限定域名。有关详细信息,请参阅 erl

通常,当引用另一个节点时,会自动建立连接。可以通过将内核配置参数 dist_auto_connect 设置为 never 来禁用此功能,请参阅 kernel(6)。在这种情况下,必须通过调用 connect_node/1 来显式建立连接。

哪些节点允许相互通信由 magic cookie 系统处理,请参阅 Erlang 参考手册中的 分布式 Erlang 部分。

警告

启动分布式节点而不指定 -proto_dist inet_tls 会使节点容易受到攻击,这些攻击可能会使攻击者完全访问节点并在扩展中访问集群。当使用不安全的分布式节点时,请确保配置网络以阻止潜在的攻击者。有关如何设置安全分布式节点的详细信息,请参阅 使用 SSL 进行 Erlang 分布用户指南。

概要

函数

允许访问指定的节点集。

建立与 Node 的连接。

返回当前使用的网络滴答时间(以秒为单位)。

获取本地节点的分布的当前状态。

获取连接到 Node 的分布套接字的一个或多个选项。

调用进程订阅或取消订阅节点状态更改消息。当新节点连接时,会向所有订阅进程传递 nodeup 消息,当节点断开连接时,会传递 nodedown 消息。

net_ticktime(请参阅 kernel(6))设置为 NetTicktime 秒。TransitionPeriod 默认为 60

设置分布套接字的一个或多个选项。参数 Node 可以是一个节点名称,也可以是原子 new,以影响所有未来连接节点的分布套接字。

start(Options) 已弃用

通过启动 net_kernel 和其他必要的进程,将非分布式节点转换为分布式节点。

通过启动 net_kernel 和其他必要的进程,将非分布式节点转换为分布式节点。

将分布式节点转换为非分布式节点。

类型

链接到此类型

connection_state()

查看源代码 (未导出)
-type connection_state() :: pending | up | up_pending.
链接到此类型

connection_type()

查看源代码 (未导出)
-type connection_type() :: normal | hidden.

函数

-spec allow(Nodes) -> ok | error when Nodes :: [node()].

允许访问指定的节点集。

在第一次调用 allow/1 之前,任何具有正确 cookie 的节点都可以连接。当调用 allow/1 时,会建立允许节点的列表。任何来自(或到)该列表中未包含的节点的访问尝试都将被拒绝。

后续对 allow/1 的调用会将指定的节点添加到允许的节点列表中。无法从列表中删除节点。

如果 Nodes 中的任何元素不是原子,则返回 error

-spec connect_node(Node) -> boolean() | ignored when Node :: node().

建立与 Node 的连接。

如果建立了连接或已建立连接,或者如果 Node 是本地节点本身,则返回 true。如果连接尝试失败,则返回 false,如果本地节点未处于活动状态,则返回 ignored

-spec get_net_ticktime() -> Res
                          when
                              Res :: NetTicktime | {ongoing_change_to, NetTicktime} | ignored,
                              NetTicktime :: pos_integer().

返回当前使用的网络滴答时间(以秒为单位)。

有关详细信息,请参阅 net_ticktime Kernel 参数。

定义的返回值 (Res)

  • NetTicktime - net_ticktimeNetTicktime 秒。

  • {ongoing_change_to, NetTicktime} - net_kernel 当前正在将 net_ticktime 更改为 NetTicktime 秒。

  • ignored - 本地节点未处于活动状态。

链接到此函数

get_state()

查看源代码 (自 OTP 25.0 起)
-spec get_state() ->
                   #{started => no | static | dynamic,
                     name => atom(),
                     name_type => static | dynamic,
                     name_domain => shortnames | longnames}.

获取本地节点的分布的当前状态。

返回一个包含(至少)以下键值对的映射

  • started => Started - Started 的有效值

    • no - 分布未启动。在这种状态下,映射中不存在以下其他任何键。

    • static - 分布是使用命令行参数 -name-sname 启动的。

    • dynamic - 分布是使用 net_kernel:start/1 启动的,可以使用 net_kernel:stop/0 停止。

  • name => Name - 节点的名称。与 erlang:node/0 返回的值相同,除非当 name_typedynamic 时,在这种情况下,Name 可能为 undefined(而不是 nonode@nohost)。

  • name_type => NameType - NameType 的有效值

    • static - 节点具有由节点本身设置的静态节点名称。

    • dynamic - 分布以 动态节点名称模式启动,并将从它连接的第一个节点分配其节点名称。如果键 name 的值为 undefined,则尚未发生这种情况。

  • name_domain => NameDomain - NameDomain 的有效值

    • shortnames - 分布启动时使用带有简短主机部分(非完全限定)的节点名称。

    • longnames - 分布启动时使用带有长完全限定主机部分的节点名称。

链接到此函数

getopts(Node, Options)

查看源代码 (自 OTP 19.1 起)
-spec getopts(Node, Options) -> {ok, OptionValues} | {error, Reason} | ignored
                 when
                     Node :: node(),
                     Options :: [inet:socket_getopt()],
                     OptionValues :: [inet:socket_setopt()],
                     Reason :: inet:posix() | noconnection.

获取连接到 Node 的分布套接字的一个或多个选项。

如果 Node 是已连接的节点,则返回值与 inet:getopts(Sock, Options) 的返回值相同,其中 SockNode 的分布套接字。

如果本地节点未处于活动状态,则返回 ignored,如果 Node 未连接,则返回 {error, noconnection}

-spec monitor_nodes(Flag) -> ok | Error when Flag :: boolean(), Error :: error | {error, term()}.

等效于 monitor_nodes(Flag, [])

链接到此函数

monitor_nodes(Flag, Options)

查看源代码
-spec monitor_nodes(Flag, Options) -> ok | Error
                       when
                           Flag :: boolean(),
                           Options :: OptionsList | OptionsMap,
                           OptionsList :: [ListOption],
                           ListOption :: connection_id | {node_type, NodeType} | nodedown_reason,
                           OptionsMap ::
                               #{connection_id => boolean(),
                                 node_type => NodeType,
                                 nodedown_reason => boolean()},
                           NodeType :: visible | hidden | all,
                           Error :: error | {error, term()}.

调用进程订阅或取消订阅节点状态更改消息。当新节点连接时,会向所有订阅进程传递 nodeup 消息,当节点断开连接时,会传递 nodedown 消息。

如果 Flagtrue,则开始新的订阅。如果 Flagfalse,则停止所有先前使用相同 Options 开始的订阅。如果两个选项列表包含相同的选项集,则认为它们相同。

nodeup/nodedown 消息的传递保证

  • nodeup 消息在通过新建立的连接从远程节点传递任何信号之前传递。
  • nodedown 消息在来自远程节点的所有信号通过连接传递后传递。
  • nodeup 消息在相应节点出现在 erlang:nodes() 的结果中后传递。
  • nodedown 消息在相应节点从 erlang:nodes() 的结果中消失后传递。
  • 从 OTP 23.0 开始,将关闭连接的 nodedown 消息将在由于与同一节点的新连接而产生的 nodeup 消息之前传递。在 OTP 23.0 之前,不保证这种情况。

节点状态更改消息的格式取决于 Options。如果 Options 是空列表,或者如果调用了 net_kernel:monitor_nodes/1,则格式如下

{nodeup, Node} | {nodedown, Node}
  Node = node()

Options 为空映射或空列表时,调用方将仅订阅可见节点的状态更改消息。也就是说,仅订阅出现在 erlang:nodes/0 的结果中的节点。

如果 Options 不等于空列表,则状态更改消息的格式如下

{nodeup, Node, Info} | {nodedown, Node, Info}
  Node = node()
  Info = #{Tag => Val} | [{Tag, Val}]

Info 是映射或 2 元组列表。其内容取决于 Options。如果 Options 是映射,则 Info 也将是映射。如果 Options 是列表,则 Info 也将是列表。

Options 是映射时,目前允许以下关联

  • connection_id => boolean() - 如果关联的值等于 true,则 Info 映射中将包含 connection_id => ConnectionId 关联,其中 ConnectionId 是正在启动或关闭的连接的连接标识符。有关此连接标识符的更多信息,请参阅 erlang:nodes/2 的文档。

  • node_type => NodeType - NodeType 的有效值

    • visible - 仅订阅可见节点的节点状态更改消息。Info 映射中将包含关联 node_type => visible

    • hidden - 仅订阅隐藏节点的状态更改消息。关联 node_type => hidden 将包含在 Info 映射中。

    • all - 订阅可见和隐藏节点的状态更改消息。关联 node_type => visible | hidden 将包含在 Info 映射中。

    如果 Options 映射中未包含 node_type => NodeType 关联,则调用者将仅订阅可见节点的状态更改消息,但 Info 映射中将包含 node_type => visible 关联。

  • nodedown_reason => boolean() - 如果该关联的值等于 true,则 nodedown 消息的 Info 映射中将包含 nodedown_reason => Reason 关联。

    Reason 可以是任何项,具体取决于所使用的分发模块或进程,但对于标准的 TCP 分发模块,它是以下之一

    • connection_setup_failed - 连接设置失败(在发送 nodeup 消息后)。

    • no_network - 没有可用的网络。

    • net_kernel_terminated - net_kernel 进程终止。

    • shutdown - 未指定的连接关闭。

    • connection_closed - 连接已关闭。

    • disconnect - 连接已断开(从当前节点强制断开)。

    • net_tick_timeout - 网络心跳超时。

    • send_net_tick_failed - 无法通过连接发送网络心跳。

    • get_status_failed - 从保存连接的 Port 中检索状态信息失败。

Options 是一个列表时,目前 ListOption 可以是以下之一

  • connection_id - Info 中将包含一个 {connection_id, ConnectionId} 元组,其中 ConnectionId 是正在建立或关闭的连接的连接标识符。有关此连接标识符的更多信息,请参阅 erlang:nodes/2 的文档。

  • {node_type, NodeType} - NodeType 的有效值

    • visible - 仅订阅可见节点的状态更改消息。元组 {node_type, visible} 将包含在 Info 列表中。

    • hidden - 仅订阅隐藏节点的状态更改消息。元组 {node_type, hidden} 将包含在 Info 列表中。

    • all - 订阅可见和隐藏节点的状态更改消息。元组 {node_type, visible | hidden} 将包含在 Info 列表中。

    如果未提供任何 {node_type, NodeType} 选项。调用者将仅订阅可见节点的状态更改消息,但 Info 列表中将包含 {node_type, visible} 元组。

  • nodedown_reason - nodedown 消息的 Info 列表中将包含元组 {nodedown_reason, Reason}

    有关可能的 Reason 值的信息,请参阅上面 nodedown_reason => boolean() 关联的文档。

示例

(a@localhost)1> net_kernel:monitor_nodes(true, #{connection_id=>true, node_type=>all, nodedown_reason=>true}).
ok
(a@localhost)2> flush().
Shell got {nodeup,b@localhost,
                  #{connection_id => 3067552,node_type => visible}}
Shell got {nodeup,c@localhost,
                  #{connection_id => 13892107,node_type => hidden}}
Shell got {nodedown,b@localhost,
                    #{connection_id => 3067552,node_type => visible,
                      nodedown_reason => connection_closed}}
Shell got {nodedown,c@localhost,
                    #{connection_id => 13892107,node_type => hidden,
                      nodedown_reason => net_tick_timeout}}
Shell got {nodeup,b@localhost,
                  #{connection_id => 3067553,node_type => visible}}
ok
(a@localhost)3>
链接到此函数

set_net_ticktime(NetTicktime)

查看源代码
-spec set_net_ticktime(NetTicktime) -> Res
                          when
                              NetTicktime :: pos_integer(),
                              Res :: unchanged | change_initiated | {ongoing_change_to, NewNetTicktime},
                              NewNetTicktime :: pos_integer().

等效于 set_net_ticktime(NetTicktime, 60)

链接到此函数

set_net_ticktime(NetTicktime, TransitionPeriod)

查看源代码
-spec set_net_ticktime(NetTicktime, TransitionPeriod) -> Res
                          when
                              NetTicktime :: pos_integer(),
                              TransitionPeriod :: non_neg_integer(),
                              Res :: unchanged | change_initiated | {ongoing_change_to, NewNetTicktime},
                              NewNetTicktime :: pos_integer().

net_ticktime(请参阅 kernel(6))设置为 NetTicktime 秒。TransitionPeriod 默认为 60

一些定义

  • 最小转换流量间隔 (MTTI) - minimum(NetTicktime, PreviousNetTicktime)*1000 div 4 毫秒。

  • 转换期 - 覆盖调用 set_net_ticktime/2TransitionPeriod 秒所需的最少连续 MTTI 时间(即 ((TransitionPeriod*1000 - 1) div MTTI + 1)*MTTI 毫秒)。

如果 NetTicktime < PreviousNetTicktime,则 net_ticktime 更改在转换期结束时完成;否则在开始时完成。在转换期间,net_kernel 确保所有连接上至少每 MTTI 毫秒有一次传出流量。

注意

必须在任何节点上的任何转换期结束之前,在网络中的所有节点上启动 net_ticktime 更改(使用相同的 NetTicktime);否则连接可能会被错误地断开。

返回以下之一

  • unchanged - net_ticktime 已具有 NetTicktime 的值,并且保持不变。

  • change_initiated - net_kernel 启动了将 net_ticktime 更改为 NetTicktime 秒的操作。

  • {ongoing_change_to, NewNetTicktime} - 该请求被忽略,因为 net_kernel 正忙于将 net_ticktime 更改为 NewNetTicktime 秒。

链接到此函数

setopts(Node, Options)

查看源代码 (自 OTP 19.1 起)
-spec setopts(Node, Options) -> ok | {error, Reason} | ignored
                 when
                     Node :: node() | new,
                     Options :: [inet:socket_setopt()],
                     Reason :: inet:posix() | noconnection.

设置分布套接字的一个或多个选项。参数 Node 可以是一个节点名称,也可以是原子 new,以影响所有未来连接节点的分布套接字。

返回值与 inet:setopts/2 的返回值相同,如果 Node 不是已连接的节点或 new,则返回 {error, noconnection}

如果 Nodenew,则 Options 也将添加到内核配置参数 inet_dist_listen_optionsinet_dist_connect_options 中。

如果本地节点未启动,则返回 ignored

此函数已弃用。请改用 start/2。
-spec start(Options) -> {ok, pid()} | {error, Reason}
               when
                   Options :: [Name | NameDomain | TickTime, ...],
                   Name :: atom(),
                   NameDomain :: shortnames | longnames,
                   TickTime :: pos_integer(),
                   Reason :: {already_started, pid()} | term().

通过启动 net_kernel 和其他必要的进程,将非分布式节点转换为分布式节点。

Options 列表只能是以下列表之一(顺序很重要)

链接到此函数

start(Name, Options)

查看源代码 (自 OTP 24.3 起)
-spec start(Name, Options) -> {ok, pid()} | {error, Reason}
               when
                   Options ::
                       #{name_domain => NameDomain,
                         net_ticktime => NetTickTime,
                         net_tickintensity => NetTickIntensity,
                         dist_listen => boolean(),
                         hidden => boolean()},
                   Name :: atom(),
                   NameDomain :: shortnames | longnames,
                   NetTickTime :: pos_integer(),
                   NetTickIntensity :: 4..1000,
                   Reason :: {already_started, pid()} | term().

通过启动 net_kernel 和其他必要的进程,将非分布式节点转换为分布式节点。

如果 Name 设置为undefined,则将启动分发以从它连接的第一个节点请求动态节点名称。请参阅 动态节点名称。将 Name 设置为 undefined 意味着选项 dist_listen => falsehidden => true

当前支持的选项

  • name_domain => NameDomain - 确定节点名称的主机名部分。如果 NameDomain 等于 longnames,则将使用完全限定的域名,这也是默认值。如果 NameDomain 等于 shortnames,则仅使用主机的短名称。

  • net_ticktime => NetTickTime - 要使用的网络心跳时间(以秒为单位)。默认为 net_ticktime kernel(6) 参数的值。有关网络心跳时间的更多信息,请参阅 kernel 参数。但是,请注意,如果 kernel 参数的值无效,它将静默地替换为有效值,但如果将无效的 NetTickTime 值作为选项值传递给此函数,则调用将失败。

  • net_tickintensity => NetTickIntensity - 要使用的网络心跳强度。默认为 net_tickintensity kernel(6) 参数的值。有关网络心跳强度的更多信息,请参阅 kernel 参数。但是,请注意,如果 kernel 参数的值无效,它将静默地替换为有效值,但如果将无效的 NetTickIntensity 值作为选项值传递给此函数,则调用将失败。

  • dist_listen => boolean() - 启用或禁用侦听传入连接。默认为 -dist_listen erl 命令行参数的值。请注意,dist_listen => false 意味着 hidden => true

    如果将 undefined 作为 Name 传递,则 dist_listen 选项将被 dist_listen => false 覆盖。

  • hidden => boolean() - 启用或禁用隐藏节点。如果已传递 -hidden erl 命令行参数,则默认为 true;否则为 false

    如果将 undefined 作为 Name 传递,或者选项 dist_listen 等于 false,则 hidden 选项将被 hidden => true 覆盖。

-spec stop() -> ok | {error, Reason} when Reason :: not_allowed | not_found.

将分布式节点转换为非分布式节点。

对于网络中的其他节点,这与节点关闭相同。仅当使用 start/2 启动网络内核时才有可能,否则返回 {error, not_allowed}。如果本地节点未启动,则返回 {error, not_found}