分布式游戏框架上线运行一周,发现服务端的内存每天都在涨。
虽然使用win30 API 强制回收垃圾,也很快就涨回来了!查看消息队列,没有消息积压。开始以为是rabbitmq的问题也没有太在意。直到打开测试服务端,发现测试服务器端已经不工作了,rabbtmq 罢工。内存占用1.3G。用win30 API 释放内存后,任务管理器显示占用内存60MB。但是启动服务端程序,可以连接上rabbitmq 却无法发送与接收消息。
先是检查了rabbitmq 运行日志,没有看到有任何的错误。
看rabbitmq Overview 也显示比较正常。
Connections 中显示连接为 blocked 与 blockeding 这才知道rabbitmq停止工作的真正原因。
connection.ConnectionBlocked += ConnectionBlockedEventHandler;
connection.ConnectionUnblocked += ConnectionUnblockedEventHandler;
rabbitmq连接中有两个事件ConnectionBlocked、ConnectionUnblocked分别表示消息阻塞与解除阻塞事件。实现后发现 收到 ConnectionBlocked 事件 Reason 显示 low on memory。
erl.exe 占用内存很低,Overview 显示的内存 还不是 rabbitmq 真正占用的内存。
在Overview 中找到主机名,点击可查看 主机的运行情况
打开后可看到如下图所示,但是服务器 memory limit 是1.6G - Used 显示82M 这里也是显示出错的,出错的原因不太清楚,Used 内存没有拿到真实的。
重点往下找
点击 memory details 中的 Update
(以下不是出错时的场景,当时是 显示 Runtime Used 与 Runtime Allocated 都是1.7G,细节中 binaries ,Processes 中的plugins 与 other 都占用较高的内存值。)
再观察
Advanced 中的三个图 GC,GC bytes reclaimed,Context switches 值都是 0 ,一条直线。
rabbitmq 不工作是导致内存一直涨的主要原因。
经过层层排查,发现是 命令行加密工具导致了 rabbitmq 的GC 无法运行,导致了内存的积压。如果你跟我一样,或者类似。 不要马上关闭命令行加密。由于前面的内存垃圾,导致GC一次处理过多,会瞬间把内存吃光!!! 一定要做好准备再关闭。
要测试资源耗尽 可以设置 内存的上下限,硬盘空间等。 当rabbitmq 使用资源超过上限时会进入blocked 状态,当资源充足时会自动 UnBlocked , 在Connection 中的ConnectionBlocked 与 ConnectionUnBlocked 无实际作用,只触发事件,不更改状态