檢視原始碼 net_kernel (kernel v10.2)
Erlang 網路核心。
網路核心是一個系統程序,註冊為 net_kernel
,它必須在分散式 Erlang 運作時處於啟用狀態。此程序的目的在於實作 BIFs spawn/4
和 spawn_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。
透過啟動 net_kernel
和其他必要的程序,將非分散式節點轉換為分散式節點。
透過啟動 net_kernel
和其他必要的程序,將非分散式節點轉換為分散式節點。
將分散式節點轉換為非分散式節點。
類型
函式
-spec allow(Nodes) -> ok | error when Nodes :: [node()].
允許存取指定的節點集合。
在第一次呼叫 allow/1
之前,任何具有正確 cookie 的節點都可以連線。當呼叫 allow/1
時,會建立允許的節點清單。任何來自(或傳送至)不在該清單中的節點的存取嘗試都會遭到拒絕。
後續呼叫 allow/1
會將指定的節點新增至允許的節點清單。無法從清單中移除節點。
如果 Nodes
中的任何元素不是原子,則傳回 error
。
建立與 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_ticktime
為NetTicktime
秒。{ongoing_change_to, NetTicktime}
-net_kernel
目前正在將net_ticktime
變更為NetTicktime
秒。ignored
- 本機節點未執行。
-spec get_state() -> #{started => no | static | dynamic, name => atom(), name_type => static | dynamic, name_domain => shortnames | longnames}.
取得本機節點的分散式處理目前狀態。
傳回一個映射,其中包含(至少)以下鍵值組
started => Started
-Started
的有效值no
- 分散式處理未啟動。在此狀態下,映射中不存在以下的其他任何鍵。dynamic
- 分散式處理是使用net_kernel:start/1
啟動的,並且可以使用net_kernel:stop/0
停止。
name => Name
- 節點的名稱。與erlang:node/0
傳回的值相同,除非name_type
為dynamic
,在這種情況下,Name
可能會是undefined
(而不是nonode@nohost
)。name_type => NameType
-NameType
的有效值static
- 節點具有由節點本身設定的靜態節點名稱。dynamic
- 分散式處理是在 動態節點名稱 模式下啟動的,並且會從其連線的第一個節點取得其節點名稱。如果鍵name
的值為undefined
,表示尚未發生這種情況。
name_domain => NameDomain
-NameDomain
的有效值shortnames
- 分散式處理啟動時使用具有簡短主機部分的節點名稱(非完整)。longnames
- 分散式處理啟動時使用具有長完整主機部分的節點名稱。
-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)
相同,其中 Sock
是 Node
的分散式 socket。
如果本機節點未執行,則傳回 ignored
,如果 Node
未連線,則傳回 {error, noconnection}
。
-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
訊息。
如果 Flag
為 true
,則會啟動新的訂閱。如果 Flag
為 false
,則會停止所有先前使用相同 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>
-spec set_net_ticktime(NetTicktime) -> Res when NetTicktime :: pos_integer(), Res :: unchanged | change_initiated | {ongoing_change_to, NewNetTicktime}, NewNetTicktime :: pos_integer().
-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
秒。
-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}
。
如果 Node
為 new
,則 Options
也會被新增到核心配置參數 inet_dist_listen_options 和 inet_dist_connect_options。
如果本機節點未啟動,則返回 ignored
。
-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
列表只能是以下列表之一(順序很重要):
[Name]
- 與net_kernel:start([Name, longnames, 15000])
相同。[Name, NameDomain]
- 與net_kernel:start([Name, NameDomain, 15000])
相同。[Name, NameDomain, TickTime]
- 與net_kernel:start(Name, #{name_domain => NameDomain, net_ticktime => ((TickTime*4-1) div 1000) + 1, net_tickintensity => 4})
相同。請注意,TickTime
與以毫秒為單位的網路計時不相同。TickTime
是當網路計時強度等於4
時,計時之間的間隔時間。
-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 => false
和 hidden => 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}
。