Linux仮想マシンで実行されているnode.jsに単純なアプリケーションがあります。TCP メッセージをリッスンし、socket.io ライブラリを使用してクライアントに送信します。そして、CPU使用率が低い状態がしばらく続いた後、アプリケーションがハングアップするまで、突然CPUの負荷が高くなり始めます。スクリプトは単純で、何が問題なのか理解できません。
var net = require('net');
var io = require('socket.io').listen(socketPort);
net.createServer(function (socket) {
socket.setEncoding("utf8");
socket.on('data', function (dataStr) {
console.log("TCP dataStr " + dataStr);
var data = JSON.parse(dataStr);
io.sockets.in(data.room).emit('publish', data);
});
}).listen(tcpPort);
io.sockets.on('connection', function (socket) {
socket.on('subscribe', function (room) {
console.log('subscribe room ' + room);
if (Array.isArray(room)) {
var i;
for (i = 0; i < room.length; i++) {
console.log('subscribe join room ' + room[i]);
socket.join(room[i]);
}
} else if (typeof room === 'string') {
console.log('subscribe join room ' + room);
socket.join(room);
}
});
socket.on('unsubscribe', function (room) {
console.log('unsubscribe room ' + room);
if (Array.isArray(room)) {
var i;
for (i = 0; i < room.length; i++) {
console.log('unsubscribe leave room ' + room[i]);
socket.leave(room[i]);
}
} else if (typeof room === 'string') {
console.log('unsubscribe leave room ' + room);
socket.leave(room);
}
});
});
また、クラスターモジュールを使用して、クライアントと通信する複数のワーカーを実行しようとしました。そして、しばらくすると、すべてのワーカーが自分の CPU コアを 100% でハングアップし、約 1 分の時間差があります。
UPD:クライアント コード (ブラウザで実行):
socketObj = new function() {
var that = this;
that.socket;
that.init = function(nodeServerUrl, rooms, onPublishFunc) {
that.socket = io.connect(nodeServerUrl);
that.socket.emit('subscribe', rooms);
that.socket.on('publish', function(data) {
onPublishFunc(data);
});
};
that.subscribe = function(room) {
that.socket.emit('subscribe', room);
};
that.unsubscribe = function(room) {
that.socket.emit('unsubscribe', room);
};
}
...
try {
socketObj.init('application url', ["room1", "room2"], nodeJsCallback);
} catch(err) {
}
...
nodeJsCallback = function(jsonData) {
//Only updates data on UI, no subscribing, unsubscribing, emitting etc.
...
}
UPD2:実稼働マシンとローカル Windows マシンで模擬テストを実行して問題を再現しようとしました。私はいくつかのストレステストを行いました:
- 複数のクライアント ソケット接続
- 複数の静的データのダウンロード (ブラウザ用の socket.io スクリプト)
- tcp 更新の頻度の増加。
数時間のテストの後、再現できませんでした。しかし、本番環境で実際のユーザーが実行しているときは、ハングアップするのが早かったり遅かったりします。
これは環境または特定のメッセージの問題であると考え始めています。おそらく次に試すことは次のとおりです。
- Node.js を現在のバージョンに更新する
- すべてのデータ転送をログに記録し、ハングが再現されることを期待して後で再生してみてください