Mam prostą aplikację na węźle node.js działającym na maszynie wirtualnej Linux. Wysłuchuje komunikatów TCP i wysyła je do klientów za pomocą biblioteki socket.io. Po pewnym czasie niskiego użycia procesora nagle zaczyna się ładować procesor coraz wyżej, aż do momentu, gdy aplikacja się zawiesi. Skrypt jest prosty i nie mogę zrozumieć, co jest z nim nie tak.Aplikacja node.js nagle ładuje procesor na 100% i zawiesza się
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);
}
});
});
Również z modułem klastra próbowałem uruchomić wielu pracowników, którzy komunikują się z klientami. I każdy pracownik po pewnym czasie zawiesza własny rdzeń procesora na 100% z różnicą czasu około minuty.
UPD: kod klienta (uruchamiane w przeglądarce):
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: Starałem się odtworzyć problem z syntetycznych testów na maszynie produkcyjnej i na moim komputerze lokalnym Windows. Zrobiłem kilka testów warunków skrajnych:
- wiele połączeń z gniazdem klient
- Wielokrotne pobieranie danych statycznych (socket.io skrypt do przeglądarki)
- Zwiększona FREQUENCE TCP aktualizacji.
Po kilku godzinach testów nie udało mi się odtworzyć. Ale gdy jest uruchamiany z rzeczywistymi użytkownikami, jest zawieszany wcześniej lub później.
Zaczynam myśleć, że jest to problem środowiskowy lub specyficzny komunikat. Prawdopodobnie kolejne rzeczy postaram są:
- Aktualizacja node.js do aktualnej wersji
- próby logowania cały transfer danych i odtworzyć ją później w nadziei wiszące odtworzy
Czy używasz sklepu RedisStore do sklepu socket.io? – JAM
To pierwsza wersja skryptu. W tym przypadku nie używam Redis jako pamięci i mam 1 proces. Druga wersja korzysta z socket.io z Redis, 1 odsłuchu dla wiadomości tcp i przekazania do 2 procedur, które komunikują się z przeglądarkami klienta. Wisi też druga wersja. – ooops
Czy Twoje wersje Node/socket.io są aktualne? – robertklep