檢視原始碼 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

通常,當引用另一個節點時,會自動建立連線。可以透過將 Kernel 設定參數 dist_auto_connect 設定為 never 來停用此功能,請參閱 kernel(6)。在這種情況下,必須透過呼叫 connect_node/1 來明確地建立連線。

哪些節點可以彼此通訊是由 magic cookie 系統處理的,請參閱 Erlang 參考手冊中的 分散式 Erlang 章節。

警告

啟動分散式節點而不指定 -proto_dist inet_tls 將使節點暴露於攻擊之下,攻擊者可能會完全存取該節點,進而存取叢集。當使用不安全的分散式節點時,請確保網路設定可以將潛在的攻擊者阻擋在外。有關如何設定安全分散式節點的詳細資訊,請參閱 使用 SSL 進行 Erlang 分散式處理 使用者指南。

摘要

函式

允許存取指定的節點集合。

建立與 Node 的連線。

以秒為單位傳回目前使用的網路 tick 時間。

取得本機節點的分散式處理目前狀態。

取得連線至 Node 的分散式 socket 的一個或多個選項。

呼叫程序會訂閱或取消訂閱節點狀態變更訊息。當連線新的節點時,會向所有訂閱的程序傳送 nodeup 訊息,而當節點斷線時,會傳送 nodedown 訊息。

net_ticktime (請參閱 kernel(6)) 設定為 NetTicktime 秒。TransitionPeriod 的預設值為 60

設定分散式 socket 的一個或多個選項。引數 Node 可以是一個節點名稱,也可以是原子 new,以影響所有未來連線節點的分散式 socket。

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().

以秒為單位傳回目前使用的網路 tick 時間。

有關更多資訊,請參閱 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 的分散式 socket 的一個或多個選項。

如果 Node 是已連線的節點,則傳回值與 inet:getopts(Sock, Options) 相同,其中 SockNode 的分散式 socket。

如果本機節點未執行,則傳回 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 - 僅訂閱隱藏節點的節點狀態變更訊息。 Info 映射表中會包含 node_type => hidden 關聯。

    • all - 訂閱可見和隱藏節點的節點狀態變更訊息。 Info 映射表中會包含 node_type => visible | hidden 關聯。

    如果 Options 映射表中未包含 node_type => NodeType 關聯,則呼叫者將僅訂閱可見節點的狀態變更訊息,但 Info 映射表中將包含 node_type => visible 關聯。

  • nodedown_reason => boolean() - 如果關聯的值等於 true,則 nodedown 訊息的 Info 映射表中會包含一個 nodedown_reason => Reason 關聯。

    Reason 可以是任何 term,具體取決於所使用的分發模組或程序,但對於標準 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 - 僅訂閱可見節點的節點狀態變更訊息。 Info 列表中會包含 {node_type, visible} 元組。

    • hidden - 僅訂閱隱藏節點的節點狀態變更訊息。 Info 列表中會包含 {node_type, hidden} 元組。

    • all - 訂閱可見和隱藏節點的節點狀態變更訊息。 Info 列表中會包含 {node_type, visible | hidden} 元組。

    如果未提供 {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/2 後,覆蓋 TransitionPeriod 秒所需的最少連續 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.

設定分散式 socket 的一個或多個選項。引數 Node 可以是一個節點名稱,也可以是原子 new,以影響所有未來連線節點的分散式 socket。

返回值與 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}