随着部署了WebSocket应用程序,Tomcat的内存逐渐耗尽

2022-09-02 10:58:11

我在一个AWS盒子上运行了Tomcat 8.5.9,其中部署了10个不同的WebSocket应用程序,每个应用程序基本上都充当消息代理。https 连接器使用的是 Http11NioProtocol。我设置的唯一参数是 maxThreads=200 以及证书信息。

请求量不是很高。它自周一早上以来一直在运行,以下是经理状态所说的:

最大线程数: 200
当前线程计数: 38
当前线程忙: 0
保持活动状态套接字计数: 1
最大处理时间: 234 毫秒
处理时间: 17.254 s
请求计数: 33351
错误计数: 325
收到的字节数: 0.00 MB
发送的字节数: 34.07 MB

几天后,我注意到内存使用量继续增长。我必须大约每两周左右重新启动一次Tomcat服务,以防止出现OutOfMemoryException。

我一直在使用Eclipse MAT进行堆转储和分析,它总是指出WsFrameServer类是可疑的问题。最近的转储显示以下内容:

由“java.net.URLClassLoader @ 0x6c0047c28”
加载的“org.apache.tomcat.websocket.server.WsFrameServer”的5,146个实例占用1,383,143,200
(73.13%)字节。这些实例是从“java.util.concurrent.ConcurrentHashMap$Node[]”的
一个实例引用的。

支配者树目前有106,000个条目,其中大部分是WsFrameServer类。

是我做错了什么还是这是“正常”?在 Tomcat 或连接器上是否有任何特定设置,我应该设置这些设置以防止这种情况发生?

提前致谢。

编辑:我不确定这是否有帮助,但这是VisualVM监视器的样子:

VisualVM Monitor


答案 1

如果没有更多细节,很难确定,但这可能与您的会话保留有关。我认为正在发生的事情是,哪个扩展被添加到会话中。
如果您有无限制的会话保留策略,那么您最终会耗尽内存。WsFrameServerWsFrameBase

尝试设置非 0sessionTimeout


答案 2

您的问题中缺少代码。(特别是您如何管理 websocket 连接)

您是否在异步模式下使用tomcat,并在某个地方使用连接列表?

您不要忘记将关闭 AND 错误事件绑定到从列表中删除错误连接的代码?