【发布时间】:2020-03-09 22:44:45
【问题描述】:
我在 Heroku 上托管一个运行在 NodeJS 服务器上的游戏网站。客户端通过使用包socket.io 的套接字连接。
偶尔触发垃圾回收周期时,连接的客户端会遇到严重的延迟,并且经常会出现断开连接。客户通过延迟的传入聊天和延迟的游戏输入体验到这一点。
当我查看日志时,我发现了与垃圾收集相关的错误消息。请参阅下面的附加日志。当这些 GC 事件发生时,有时它会导致大量内存峰值,以至于应用程序超过允许的 0.5GB RAM 并被 Heroku 杀死。然而,最近,内存峰值不再经常发生,但客户端的严重延迟仍然每天大约发生一两次。
延迟的一个方面是通过聊天。当用户通过“所有聊天”(和任何聊天频道)键入消息时,服务器当前console.log() 将其发送到标准输出。我碰巧在峰值事件期间观看了一次实时日志,并注意到实时输出到终端的聊天没有延迟,但是客户(我自己也是网站上的客户)收到了这些消息很延迟的时尚。
我在网上发现了一个 NodeJS 错误(我认为已修复),当太多console.loged 显示在屏幕上时会导致严重滞后,所以我通过每秒从客户端发送 1000 条消息来运行压力测试,一分钟。我无法重现尖峰。
我已经阅读了许多关于查找内存泄漏、检查堆栈等的指南,但我非常不确定如何在实时 Heroku 服务器上运行这些测试。我怀疑我的游戏对象在关闭时没有立即被清除,而是一次全部清除,导致内存峰值,但我不自信。我不知道如何最好地调试它。我也很难实时捕捉到这种情况,因为它只在超过 30 人登录时才会发生(不经常发生,因为这仍然是一个相当小的站点)。
错误消息包括对我使用的circular-json 模块的引用,并且我还怀疑这可能会以某种方式导致自身无限回调并且无法正确清除,但我不确定。
供参考,这里是源代码的副本:LINK
这是一个峰值发生时内存的 sn-p: Memory spike
崩溃日志 1:HERE
崩溃日志 2:HERE
有没有一种方法可以在本地模拟套接字或模拟实时服务器的环境(即连接的客户端)?
任何有关如何解决或调试此问题的建议将不胜感激。谢谢。
【问题讨论】:
标签: node.js socket.io garbage-collection