这次我们碰到了一个问题,疑似port泄露而导致了beam崩溃。
我们用erlang:length(erlang:ports()).在服务器控制台执行查看了当前占用端口数:32000+
然后自然想到了上限的设置,查看了启动配置:
POLL=true
SMP=auto
ERL_MAX_PORTS=32000
ERL_PROCESSES=500000
ERL_MAX_ETS_TABLES=1400
export ERL_MAX_PORTS
export ERL_MAX_ETS_TABLES
在配置中上面设置的最大上限是32000.....悲剧了,当天我们的服务器就没法再新开端口了,不停地大量报错,到晚上的时候服务器还离奇地宕机了
然后查找了erlang相关文章,庆亮大神的一篇博客也就提到了,导致的原因应该是一样的,就是客户端在压缩了数据包传给服务器端后,服务器端在调用zlib:uncompress(Data)解压缩数据时,传入的Data参数不对,导致系统异常,port未正常关闭从而使port发生大量溢出,从而导致beam崩溃,服务器宕机
原文如下:
erlang zlib引起的系统崩溃记录
在这篇文章中针对这个问题已经分析得相当透彻,并且庆亮也对于erlang的细节提出了针对性的意见:
“erlang在遇到port返回错误时直接error了,典型的非防御性编程。但是个人认为这个接口应该在抛出错误之前关闭掉打开的port。”
然后我又去找了erlang的版本更新介绍。针对上面提出的非防御性编程引发的可能漏洞,erlang R15B01已经做了相关修复,请查看15B01的更新说明文件:
Bug fix release : otp_src_R15B01Build date : 2012-04-02
上面有一段话说到了:
OTP-9981 Fix port leak in zlib when passing invalid data to compress,uncompress,zip,unzip,gzip,gunzip.
(修复向函数compress,uncompress,zip,unzip,gzip,gunzip这几个函数当传入非法数据时会导致端口泄露的bug)
说明其在15B01中就已经修复了这个问题,在找不到具体是哪个地方调用传参错误情况下,升级系统至R15B01是最好的解决办法