游戏服和大区服(也有的叫网关服的)短暂断连并短时间内又再次链接。
考虑可能是
1.大区服服务器网络问题(同事同时间没出现问题,pass)。
2.配置问题引发(是能正常连接的,pass)。
3.游戏服网络问题(就是它!!!!)。
由此开始了解EPMD(Erlang Port Mapper Daemon)。
什么是epmd?
epmd 代表 Erlang 端口映射守护进程(Erlang Port Mapper Daemon),默认绑定在4369端口上。每启动一个节点(-name/-sname),都会检查本地机器上是否运行着 epmd ,如果没有,节点就会自行启动 epmd ,epmd 会追踪在本地机器上运行的每个节点,并记录分配给它们的端口。epmd负责维护集群内的节点连接,提供节点名称到IP地址及端口的解析服务,相当于一个内置的DNS服务。
源码可以查看$OTP/erts/epmd目录。
【epmd.c】
函数 epmd_dbg 是对函数 epmd 的封装,便于在 debug 模式下使用 epmd ;
给出了如何在 linux 和 windows 上实现 daemon 函数,以及与 syslog 的配合;
【epmd.h】
定义了 epmd 所采用协议的消息编码(C语言侧定义)。
【epmd_int.h】
针对跨平台函数和变量进行定义。
【epmd_cli.c】
实现了 epmd 命令行功能所需的的 API 调用。
【epmd_srv.c】
基于 select 实现了 epmd 服务程序的事件驱动主循环;实现了针对上述 epmd 协议的解析。服务模型为一问一答式。
通过对 select 超时时间的约束(最大 5s),模拟了 busy server 的 delay_accept 和 delay_write 功能。
在 otp_src_xxx\lib\kernel\src\ 中,在 erlang 代码层面实现了与 epmd 服务程序的协议交互。
【erl_epmd.erl】
基于 gen_server 行为模式、采用 TCP socket 方式与本地或远端 epmd 进行协议通信的实现。
【erl_epmd.hrl】
定义了 epmd 所使用协议的消息编码(Erlang 语言侧定义)。
在 otp_src_xxx\lib\erl_interface\src\epmd\ 中,与 erlang 层实现对应的底层 C 实现。
【ei_epmd.h】
常量定义。
【epmd_port.c】
通过 TCP socket 连接本地或远端 epmd ,并通过协议 EPMD_PORT2_REQ 获取 the distribution port of another node 。
【epmd_publish.c】
通过协议 EPMD_ALIVE2_REQ 向隐藏 node 发布自身的 listen port 和 alive name。
【epmd_unpublish.c】
通过协议 EPMD_STOP_REQ 停止指定名字的 node。
测试流程:
初始状态、没有启动epmd:
C:\Users\Administrator>tasklist | findstr epmd
C:\Users\Administrator>tasklist | findstr beam
另外开一个窗口启动一个erlang节点:
C:\Users\Administrator>erl -sname coco
Eshell V8.3 (abort with ^G)
(coco@DESKTOP-ID25IMT)1>
再次查看 可以发现epmd已经启动
C:\Users\Administrator>tasklist | findstr epmd
epmd.exe 9676 Console 1 3,500 K
C:\Users\Administrator>tasklist | findstr beam
C:\Users\Administrator>netstat -ano | findstr "9676"
TCP 0.0.0.0:4369 0.0.0.0:0 LISTENING 9676
TCP 127.0.0.1:4369 127.0.0.1:56979 ESTABLISHED 9676
TCP [::]:4369 [::]:0 LISTENING 9676