2016-08-24 76 views
2

我試圖從一個node.js服務器流數據到很多客戶端(> 3000)。 node.js服務器從一個客戶端接收數據並將其廣播到所有客戶端。數據每秒發送一次,每個數據大約2KB。我使用ws模塊通過websocket發送數據。節點服務器凍結大量的websocket數據傳輸

節點服務器位於僅運行服務器的AWS EC2 m3.medium實例上。

客戶端在15個不同的EC2 t2.micro實例上模擬,每個實例啓動300個客戶端。

一開始一切都很好,但一段時間後(約3分鐘)服務器凍結。我無法殺死進程或在服務器上執行任何操作。但是,如果我殺死了所有客戶端(通過重新啓動所有客戶端實例),服務器再次響應。

在服務器上,CPU爲40-60%,內存爲< 1.5GB(實例爲4GB),下載帶寬約爲1.5 Mbits/sec,上傳帶寬約爲75 Mbits/sec。我做了一個速度測試,最大帶寬在下載或上傳時大約爲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)來發送數據:當處理器不是在100%,

#!/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() 

帶寬小於最大帶寬,你有什麼想法會發生什麼?

+0

因此,您有15 * 300 = 4500個客戶端,每個客戶端每秒都會向服務器發送一個2 KB數據包?這是75 Mbits/s。但是,你的服務器正在將每個收到的數據包廣播給所有4500個客戶端?這是337.5 Gbits/s。我錯過了什麼? – jcaron

+0

只有一個客戶端發送2KB到服務器。其他客戶端只接收數據而不發送任何內容。所以你對75Mbits/s是正確的 – JzSaiyan

+0

接收客戶端是否真的在使用這些數據?即它不會保持緩衝和未確認的地方? – jcaron

回答

1

正如在評論的討論中所確定的,問題在於客戶端沒有使用發送給他們的數據。

這很可能會導致未確認的消息留在內存中,等待客戶端使用它們(即使它們什麼也不做),這反過來又導致進程增長並超出可用內存。然後,它開始大量交換,或者超過可用交換,這通常不是系統處理得很好的事情。

0

它可能是一個配置問題?在linux操作系統下可以打開多少個文件描述符是有限制的。 Here有一個很好的起點,可以找到你應該如何設置機器來處理儘可能多的連接

+0

感謝您的鏈接。我已經將fd的數量設置爲100000,並試圖設置其他限制而無效。 – JzSaiyan