Erlang节点互联笔记

原创
2016/11/17 00:37
阅读数 806

最近工作上需要,游戏服需要部署到腾讯云上。打算只是登陆充值相关的部署在腾讯云上,其他游戏节点则在另外云上。实际操作下来,发现Erlang节点并不能很好的互联起来,节点只能从腾讯云上主动往外连接,反过来则不行。以前觉得理所当然的事情,现在却变得莫名其妙,所以也趁机稍微深入了解下这机制。

Q:请求连接远程节点时,节点互联是建立一条tcp链接?谁是S,谁是C?

A:腾讯云上的测试得出是谁主动连接,谁就是C。 节点互联是建立一条tcp连接,主动连接者是client,被连接的监听端口就是节点端口 同时节点启动时本身也会建立一个连接到EPMD上,用于获取、更新节点信息

根据实验结果去看代码 net_sup进程树

  • <0.21.0>:inet_tcp_dist, 启动时调用erl_epmd向EPMD注册本节点信息
  • <0.22.0>:ticker

主动连接方:

net_kernel进程查询sys_dist表连接的节点信息,如果没有,就进入建立连接步骤 inet_tcp_dist:setup,根据对方的节点名获取host,得到对应的IP,然后通过erl_epmd:port_please向对方的EPMD请求该节点的端口信息。并向sys_dist插入该节点信息,标记为pending。Driver:connect(IP, TcpPort, connect_options([{active, false}, {packet, 2}])) 成功后,就进入handshake阶段,详细可以参考Erlang dist protocol部分,代码就略过了。握手成功后,向net_kernel进程发送Kernel ! {self(), {nodeup,Node,Address,publish_type(Flags), true}}。net_kernel即改变节点状态为UP。

被动连接方:

inet_tcp_dist 启动监听端口,来接收其他节点的连接。经过握手协议时,会想sys_dist标记节点为pending,当握手成功后,则改为UP状态。 (注:中间忽略了其他各种连接情况下的状态转换以及处理)

回到一开始的问题,为什么只能从腾讯云上主动外网建立连接?因为开放平台 tgw 的某种奇葩设计,从外部连入的 tcp 连接都会多出一个莫名其妙的包头。如果连接后不首先发送此包头,则无法正确路由到对应的服务器,同时还需服务器去处理这多出来的包头。除非去修改Erlang底层的连接代码,否则外网是不可能直接连接上来的。

Q:在查询资料,阅读代码过程中,都会觉得Erlang这套机制安全性不太可靠的。节点互联靠cookie来验证,除此之外还有没有其他手段来进一步限制呢?

A:

关于定制EPMD默认端口

  • erl -epmd "epmd -port 7000 -daemon" -epmd_port 7000 -name nodename@IP -setcookie 123456
  • ERL_EPMD_PORT=7000 erl -name nodename@IP -setcookie 123456

实验得出这两种方式都可以附带启动以指定端口的EPMD,而不需要再另外再执行命令来启动。 第二种只支持shell环境,windows上则需另外安装下shell环境来执行即可。(注:不能完全相信别人写的东西,还是自己去实际操作才能检验出来,同时结合源码也能知道写文档上所没讲述的内容)

参考资料

展开阅读全文
打赏
0
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
0
分享
返回顶部
顶部