Erlang的hidden节点

转载请注明,来自:http://blog.csdn.net/skyman_2001

Erlang的节点之间的连接默认是transitive,即当节点A连接了节点B,节点B连接了节点C,那么节点A也与节点C互相连接,这样就组成了全连通网络。但有时我们希望连接一个节点而不去连接其他节点(比如某个节点只是用来查看集群的一些信息),这时可以通过指定该节点为hidden节点来实现(在节点启动时指定-hidden参数),hidden节点不加入集群全连通网络。hidden节点还能降低TCP/IP的连接数:因为如果一个集群里的节点数是N,则全连通的话,需要的TCP/IP连接数则为:N * (N - 1) / 2,所以将没必要全连通的节点设为hidden节点,会将该节点从全连通网络中移除,从而降低TCP/IP连接数。

注意nodes() 默认是不返回hidden节点的,指定参数hidden或connected(即nodes(hidden)或nodes(connected))可返回hidden节点的信息。

下面摘录官方文档里关于hidden节点的说明(就不翻译成中文了^ ^):

In a distributed Erlang system, it is sometimes useful to connect to a node without also connecting to all other nodes. An example could be some kind of O&M functionality used to inspect the status of a system without disturbing it. For this purpose, a hidden node may be used.

A hidden node is a node started with the command line flag -hidden. Connections between hidden nodes and other nodes are not transitive, they must be set up explicitly. Also, hidden nodes does not show up in the list of nodes returned by nodes(). Instead, nodes(hidden) or nodes(connected) must be used. This means, for example, that the hidden node will not be added to the set of nodes that global is keeping track of.

更深入的了解,可以阅读余锋老大的文章:http://www.iteye.com/topic/343088

但是hidden节点有个问题,就是不能自动同步它里面注册的全局进程名(使用global:sync/0也不行),我目前使用的一个方法是通过rpc来获得它已注册的全局进程名和对应的pid,然后在本地节点再手动注册,下面是我封装的函数:

sync_registered_names(Node) ->
	Registered_names = rpc:call(Node, global, registered_names, []),
	F = fun(Name) ->
				Pid = rpc:call(Node, global, whereis_name, [Name]),
				global:register_name(Name, Pid)
		end,
	[F(Name) || Name <- Registered_names].

不知道有没有更好的方法?若有知道的童鞋可以告知一下,不胜感激!


下面说下hide和connect_all false的区别:
看文档:

connect_all false

If this flag is present, global will not maintain a fully connected network of distributed Erlang nodes, and then global name registration cannot be used. 


hide和connect_all false都是不加入全连通网络,但2者是有区别的,摘自 http://www.iteye.com/topic/343088

1. 结果来看的话都是节点不全联通。
2. nodes() 是默认不返回hidden节点的 但是返回正常节点尽管connect_all false
3. rpc、monitor什么的都依赖nodes(),比如net_kernel:monitor_nodes(),默认是不包括hidden节点的,要包括的话,Options选项中的node_type要设为hidden或all:

Also, when OptionList == [] only visible nodes, that is, nodes that appear in the result of nodes/0, are monitored.

Option can be any of the following:

{node_type, NodeType}

Currently valid values for NodeType are:

visible
Subscribe to node status change messages for visible nodes only. The tuple {node_type, visible} is included in InfoList.
hidden
Subscribe to node status change messages for hidden nodes only. The tuple {node_type, hidden} is included in InfoList.
all
Subscribe to node status change messages for both visible and hidden nodes. The tuple {node_type, visible | hidden} is included in InfoList

4. 系统统计也会不同
5. hidden是在erts实现的 connect_all是在global模块实现的

在connect_all false情况下,调用global:sync会一直卡住,看它的实现代码:

-spec sync() -> 'ok' | {'error', Reason :: term()}.
sync() ->
    case check_sync_nodes() of
	{error, _} = Error ->
	    Error;
	SyncNodes ->
	    gen_server:call(global_name_server, {sync, SyncNodes}, infinity)
    end.

这里的call的timeout是infinity,上面的文档说了connect_all false时global name registration不可用,所以就一直等待了。

最后说一个,不同cookie的节点怎么连通呢?方法是连接前erlang:set_cookie(Node2, DiffCookie),参考:http://www.iteye.com/topic/356611

The default when a connection is established between two nodes, is to immediately connect all other visible nodes as well. This way, there is always a fully connected network. If there are nodes with different cookies, this method might be inappropriate and the command line flag -connect_all false must be set

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值