VELIK505
@VELIK505
Руководитель департамента profitcentr.com

Node.js 100% cpu 1ого ядра 3400MHZ при 5000 соединениях. Что не так?

при 5000 подключений по сокетам.
Server listening at address xxx.xxx.xxx.xx:3000
Change board to: evaviktoriya
Concurrent connections count: 72
Concurrent connections count: 101
Concurrent connections count: 140
Concurrent connections count: 173
Concurrent connections count: 209
Concurrent connections count: 232
Concurrent connections count: 259
Concurrent connections count: 291
Concurrent connections count: 308
Concurrent connections count: 335
Concurrent connections count: 358
Concurrent connections count: 370
Concurrent connections count: 391
Concurrent connections count: 404
Concurrent connections count: 412
Concurrent connections count: 429
Concurrent connections count: 452
Concurrent connections count: 465
Concurrent connections count: 477
Concurrent connections count: 502
Concurrent connections count: 509
Concurrent connections count: 506
Concurrent connections count: 520
Concurrent connections count: 506
.....
Concurrent connections count: 5015
node.js валит 1 ядро 3400MHZ на 100%.
688475ed83db4c3bbbaf864da3b919d1.jpg
скрипт безобидный. Запускается через forever
Делал по статейке настройки www.jayway.com/2015/04/13/600k-conc...-using-node-js
как они держат на таком же сервере 600к подключений? Чего я незнаю?
сам скриптик:
var _ = require('lodash');
var fs = require('fs');
var http = require('http');
var config = require('./config');
var ioServer = require('http').createServer();
var io = require('socket.io')(ioServer);
var argv = require('minimist')(process.argv.slice(2));
var mysql = require('mysql');

var port = argv.p || 3000;
var host = argv.h || 'localhost';

var connection = mysql.createConnection(config.db);
connection.connect();

var users = 0;

// Запуск socket сервера
ioServer.listen(port, host, isServerRunEvent);

// Обработка смены доски
fs.watchFile(config.boardPath, {interval: 500}, watchBoard);

// Запускаем логгер
setTimeout(logStatus, 1000);

// Запускаем оповещение
setTimeout(broadcatsUserCount, 1000);


////////////////////////////////////////////////////////////


/**
 * Обработка смены доски.
 */
function watchBoard() {
    var boardPath = config.boardPath;

    fs.stat(boardPath, function(err, stats){
        if (err) throw err;

        fs.readFile(boardPath, function (err, data) {
            if (err) throw err;

            var boardJson = JSON.parse(data);

            // Оповещаем всех пользователей о смене доски
            io.emit('update_board', {board: boardJson});

            console.log('Change board to: ' + boardJson.user);
        });
    });

    fs.unwatchFile('./test.json');
    fs.watchFile('./test.json', {interval: 500}, watchBoard);
}

/**
 * Вывод сообщения об успешном запуске.
 */
function isExpressServerRunEvent() {
    console.log('Express server listening at address %s:%d', host, (port + 1));
}

/**
 * Вывод сообщения об успешном запуске.
 */
function isServerRunEvent() {
    console.log('Socket Server listening at address %s:%d', host, port);
}

/**
 * Оповещаем пользователей о количестве онлайн-пользователях.
 */
function broadcatsUserCount() {
    connection.query('SELECT COUNT(`usonline`) FROM `still_online`', function(err, rows) {
        if (err) throw err;
        users = _.last(_.values(_.last(rows)));
        io.emit('update_user_online_counter', {users: users});
    });
    setTimeout(broadcatsUserCount, 10*1000);
}

/**
 * Логируем количество одновременных соединений в консоль.
 */
function logStatus() {
    setTimeout(logStatus, 5*1000);
    console.log("Concurrent connections count: " + users);
}
  • Вопрос задан
  • 2099 просмотров
Решения вопроса 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
то что грузится одно ядро - это легко объясняется тем что нода работает в рамках одного процесса и в принципе не может отжирать больше одного ядра (есть конечно отдельно модули позволяющие организовать и потоки и даже файберы).

Что до 100% загрузки - вероятно причина тому использование неэффективного fs.watchFile, попробуйте fs.watch и убедитесь что используется inotify.
Ответ написан
@yeti357
Для начала надо запускать с помощью модуля cluster для использования всех ядер. В дополнение к неэффективному методу fs.watchFile, добавлю что определённо не стоит считать пользователей онлайн из бд, как это сделано в broadcatsUserCount. Для информации о пользователях онлайн используйте редис или храните в памяти, тогда счётчик будет выглядеть как usersOnline.length
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы