最近工做上须要,游戏服须要部署到腾讯云上。打算只是登录充值相关的部署在腾讯云上,其余游戏节点则在另外云上。实际操做下来,发现Erlang节点并不能很好的互联起来,节点只能从腾讯云上主动往外链接,反过来则不行。之前以为理所固然的事情,如今却变得莫名其妙,因此也趁机稍微深刻了解下这机制。html
Q:请求链接远程节点时,节点互联是创建一条tcp连接?谁是S,谁是C?node
A:腾讯云上的测试得出是谁主动链接,谁就是C。 节点互联是创建一条tcp链接,主动链接者是client,被链接的监听端口就是节点端口 同时节点启动时自己也会创建一个链接到EPMD上,用于获取、更新节点信息shell
根据实验结果去看代码 windows
主动链接方:安全
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。服务器
被动链接方:cookie
inet_tcp_dist 启动监听端口,来接收其余节点的链接。通过握手协议时,会想sys_dist标记节点为pending,当握手成功后,则改成UP状态。 (注:中间忽略了其余各类链接状况下的状态转换以及处理)app
回到一开始的问题,为何只能从腾讯云上主动外网创建链接?由于开放平台 tgw 的某种奇葩设计,从外部连入的 tcp 链接都会多出一个莫名其妙的包头。若是链接后不首先发送此包头,则没法正确路由到对应的服务器,同时还需服务器去处理这多出来的包头。除非去修改Erlang底层的链接代码,不然外网是不可能直接链接上来的。tcp
Q:在查询资料,阅读代码过程当中,都会以为Erlang这套机制安全性不太可靠的。节点互联靠cookie来验证,除此以外还有没有其余手段来进一步限制呢?测试
A:
关于定制EPMD默认端口
实验得出这两种方式均可以附带启动以指定端口的EPMD,而不须要再另外再执行命令来启动。 第二种只支持shell环境,windows上则需另外安装下shell环境来执行便可。(注:不能彻底相信别人写的东西,仍是本身去实际操做才能检验出来,同时结合源码也能知道写文档上所没讲述的内容)
参考资料