2016-08-24 27 views
2

node.jsサーバーから多数のクライアント(> 3000)にデータをストリーミングしようとしています。 node.jsサーバーはあるクライアントからデータを受信し、すべてのクライアントにブロードキャストします。データは毎秒1回送信され、各データは約2KBです。 wsモジュールを使用してwebsocket経由でデータを送信します。多くのwebsocketデータ転送でノードサーバーがフリーズする

ノードサーバーは、サーバーのみを実行するAWS EC2 m3.mediumインスタンスにあります。

クライアントは15の異なるEC2 t2.microインスタンスでシミュレートされ、それぞれが300のクライアントを起動します。

最初はすべてうまくいっていますが、しばらくすると(約3分後)サーバーがフリーズします。私はプロセスを殺すことはできませんし、サーバー上の何かを行うことはできません。しかし、すべてのクライアントインスタンスをリブートすると、すべてのクライアントが終了すると、サーバーは再び応答します。

サーバー上のCPUは40〜60%、メモリは< 1.5GB(インスタンスは4GB)、ダウンロード帯域幅は約1.5Mbits /秒、アップロード帯域幅は約75Mbits/secです。私はスピードテストを行い、最大帯域幅はダウンロードまたはアップロードで約400 Mbits /秒です。

サーバーがフリーズする前に、メモリが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%ではないためと帯域幅が最大帯域幅よりも小さい場合、何が起こる可能性がありますか?

+0

15 * 300 = 4500クライアントがあり、毎秒2 KBのパケットをサーバーに送信していますか?それは75 Mbits/sです。しかし、あなたのサーバーはすべての受信パケットをすべての4500のクライアントにブロードキャストしていますか?これは337.5 Gbits/sです。私は何か見落としてますか? – jcaron

+0

1つのクライアントのみが2KBをサーバーに送信します。他のクライアントは何も送信せずにデータを受信するだけです。だから、あなたは75Mbits/sの上にいます – JzSaiyan

+0

受信側のクライアントは実際にデータを消費していますか?私。どこかでバッファリングされていて、確認されていませんか? – jcaron

答えて

1

コメントは、クライアントが送信されたデータを消費していないという問題でした。

ほとんどの場合、これによって、未確認のメッセージがクライアントで消費されるのを待っているメモリに残ります(何もしなくても)。プロセスが大きくなり、使用可能なメモリを超えました。その後、大きくスワップを開始したか、またはスワップを超えました。これは通常、システムが非常にうまく処理するものではありません。

0

設定に問題がありますか? Linux OSでいくつのファイル記述子を開くことができるかには限界があります。 Hereできるだけ多くの接続を処理するためにマシンをどのようにセットアップするべきかを知る良い出発点があります

+0

リンクをありがとう。私はすでにfdの数を100000に設定し、効果を持たない他の制限を設定しようとしました。 – JzSaiyan

関連する問題