Подтвердить что ты не робот

Приложение node.js внезапно загружает ЦП на 100% и зависает

У меня есть простое приложение на node.js, запущенном на виртуальной машине Linux. Он прослушивает сообщения tcp и отправляет их клиентам, используя библиотеку socket.io. И после некоторого времени низкого использования ЦП он внезапно начинает загружать ЦП выше и выше до тех пор, пока приложение не зависает. script прост, и я не могу понять, что с ним не так.

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);
        }

    });

});

Также с помощью модуля кластера я попытался запустить нескольких рабочих, которые общаются с клиентами. И каждый работник через некоторое время висит у своего ядра процессора на 100% с разницей времени примерно через минуту.

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 script для браузера)
  • Увеличена частота обновлений tcp.

После нескольких часов тестирования я не смог воспроизвести. Но когда он работает с реальными пользователями, он висит раньше или позже.

Я начинаю думать, что это проблема среды или конкретного сообщения. Вероятно, следующие вещи, которые я попробую сделать:

  • Обновить node.js в текущей версии
  • Попробуйте зарегистрировать всю передачу данных и воспроизвести их позже, надеясь, что повешение будет воспроизводиться
4b9b3361

Ответ 1

Изменено Nodejs из версии v0.10.4 (Стабильный) на v0.11.2 (Нестабильно). До сих пор все хорошее, потребляющее 1-2% процессора. Теперь мы тестируем v0.10.8 (Stable).

UPD В v0.10.8 приложение тоже стабильно.

Несмотря на то, что проблема исчезла на v0.10.4 (Stable), она все еще очень странная и обескураживающая.