节点服务器冻结了大量的websocket数据传输

我试图将数据从node.js服务器stream到很多客户端(> 3000)。 node.js服务器从一个客户端接收数据并将其广播到所有客户端。 数据每秒发送一次,每个数据大约2KB。 我使用ws模块通过websocket发送数据。

节点服务器位于仅运行服务器的AWS EC2 m3.medium实例上。

客户端在15个不同的EC2 t2.micro实例上模拟,每个客户端启动300个客户端。

一切都开始好,但一段时间后(约3分钟)服务器冻结。 我不能杀死进程或在服务器上做任何事情。 但是,如果我杀死了所有的客户端(通过重新启动所有的客户端实例),服务器再次响应。

在服务器上,CPU是40%到60%,内存是<1.5GB(实例有4GB),下载带宽大约是1.5Mbits / sec,上传带宽大约是75Mbits / sec。 我做了一个速度testing,下载或上传时的最大带宽约为400 Mbits / sec。

在服务器冻结之前,内存从300MB增加到1000MB。 我不知道为什么,如果是相关的。 我使用堆转储,并没有设法了解泄漏的位置。

这是服务器上的代码:

var WebSocketServer = require('ws').Server; var wss = new WebSocketServer({ port: 8080 }); var users = Array(); wss.binaryType = 'arraybuffer'; wss.on('connection', function(ws) { console.log('new user connected'); users.push(ws); console.log(users.length); ws.on('error', function(e) { console.log('onerror called'); ws.close() }); ws.on('close', function () { console.log('closed'); users.splice(users.indexOf(ws), 1); ws.close() }); ws.on('message', function(data) { if (data.length < 10) return ; var len = users.length; for (var i = 0; i < len; i++) { users[i].send(data, { binary : true }); } }); }); 

这里是发送数据的代码(在python中):

 #!/usr/bin/env python from time import sleep from websocket import create_connection #connection to server ws = create_connection(server_url) string = "Mea unum iusto virtute et, et meis munere vix. Meliore sensibus omittantur eum ne, sea quis epicuri sapientem at, fabulas consequat interesset in usu. Vix epicurei platonem ea, in vis agam accu\ sata. Quando maluisset forensibus ut nec, debitis percipitur ad vim, ne vix impetus volutpat. Quo magna viderer ne, nemore doctus copiosae cu mel, id vix dolorem omittam laboramus. Ne populo reprehendunt\ est, recteque dissentiet delicatissimi vis an. Dolores euripidis complectitur no nam, amet nominavi voluptua ut pri. Vix ex timeam iisque gubergren, ne vim error imperdiet deterruisset. An duo autem vir\ is vituperatoribus. Adversarium instructior te eam. Enim moderatius no eam, ut sit viris populo, ex fugit adolescens inciderint ius. Eum idque dolore voluptatum ex, ex pri solet commune mediocrem. In nib\ h affert pro, mei convenire salutandi argumentum at. Nec in vidisse tamquam. Eos an epicurei suavitate. Ex erat scribentur signiferumque quo. Pro ex sapientem deseruisse. Lorem essent omittam sed ad, pop\ ulo reprehendunt ut sit. Pri maiorum fierent te. Vim aeterno aperiam id. Mea ferri integre eu. Cu per nihil affert, fierent percipit accommodare nam te. Eu qui maiestatis concludaturque, at detracto coti\ dieque vel, no prima essent delicata sea. Nam at appareat reprehendunt. Ubique iudicabit consetetur eu sit. Ius et vivendo propriae prodesset, id his primis platonem, qui nostro quodsi cu. Mea ne wisi mu\ tat facete. Dolorem urbanitas theophrastus ut eam, mei no animal aliquid. Te est movet dicam, id labore latine rationibus his, nullam omnium tincidunt nec ut. Eu mundi ancillae erroribus vis, no vim popu\ lo intellegam. Sonet decore volutpat in has, vidisse appetere reprehendunt vel an, at sea ipsum munere corrumpit. Eos noluisse incorrupte reprehendunt cu, qui quidam intellegebat id, vel audire voluptua \ complectitur ne. Posse iuvaret prodesset vix ea. Urbanitas scriptorem ne eos, te soluta probatus est. Mei ex brute congue, in option saperet mel, veniam ocurreret no quo. Malorum mnesarchum ex quo. Meis \ quaeque pericula duo ei. Ei everti doctus vel." try: for i in range(100000): sleep(1) ws.send(string) print('emit', i) except: ws.close() ws.close() 

由于处理器不在100%,带宽小于最大带宽,你有什么想法会发生什么?

正如在评论中的讨论中所确定的那样,问题在于客户没有使用发送给他们的数据。

这很可能导致未被确认的消息留在内存中,等待客户端使用它们(即使它们什么也不做),这反过来导致进程增长并超出可用内存。 然后,它或者开始大量交换,或者超过可用交换,这通常不是一个系统处理得很好的事情。

它可能是一个configuration问题? 在linux操作系统下可以打开多less个文件描述符是有限制的。 这里有一个很好的起点,可以find你如何设置机器来处理尽可能多的连接