我有三个相互交流的应用程序。一个websocket服务器(1)接受来自浏览器的连接,解析url以查看所需的数据,并在内存中提供它以供客户端使用;如果没有,则从另一个名为“fetcher”的应用程序(2)请求该数据。Fetcher接收此工作,从简单的API(3)请求它并返回JSON数据,然后将其发送回到Websocket服务器,该服务器将其发布到连接的客户端。然后,“fetcher”开始定期检查URL/任务是否有更新,并在发生更新时将新数据发送到websocket服务器。
我使用socket.io进行客户端-WebSocket服务器通信。 WebSocket服务器和fetcher通过 ZMQ 套接字进行通信。
我使用 130个连接对websocket服务器进行负载测试。 Websocket服务器每秒向130个客户端发布160KB的数据。一开始,对于130个连接,它使用170MB的RAM,但很快就增加到1GB,尽管没有新的连接。然后,socket.io的心跳信号开始失败,导致连接断开。
我使用Nodetime拍摄堆快照。第130个客户端连接后,内存的情况如下:
共有 346个Buffer对象,总计 44MB 。
在四分钟内,缓冲区对象的数量急剧增加(同样,没有新的连接):共有3012个缓冲区对象,总内存为 486MB 。再过10分钟,有3535个缓冲区对象,总内存消耗量为 573MB 。
我使用Mozilla的memwatch找出哪一行会导致内存增加,并发现是这个函数:
function notifyObservers(resourceId) {
var data = resourceData[resourceId];
io.sockets.in(resourceId).emit('data', data);
}
如果我将这些行注释掉,内存使用量保持不变,这是另一个确认。你有什么想法这是如何发生的吗?我在ZMQ的订阅者套接字方法中调用此函数,我怀疑这与此有关。如果我删除函数并将它们合并为一个函数,则会得到以下代码:// Receive new resource data
const resourceUpdatedSubscriber = zmq.socket('sub').connect('tcp://localhost:5433');
resourceUpdatedSubscriber.subscribe('');
resourceUpdatedSubscriber.on('message', function (data) {
var resource = JSON.parse(data);
resourceData[resource.id] = resource.data;
io.sockets.in(resourceId).emit('data', resourceData[resource.id]);
});
我的所有代码(包括负载测试)都是公开的,您可以在此处找到此 WebSocket 服务器:https://github.com/denizozger/node-socketio/blob/master/server.js请查看第138行。
我两个月前开始学习 JavaScript 和 Node.js,所以欢迎任何评论。谢谢!
resourceUpdatedSubscriber.on('message', function (data) { io.sockets.emit('data', data); });
重要的是:如果我静态地提供相同的数据(即var bigData = require('./bigdata.json');
),我就没有任何问题。每当我使用来自ZMQ发布者并进行“emit”的数据时,我就会遇到内存问题。仍在努力解决中... - Deniz Ozger