Производительность сервера Socket.IO и использование полосы пропускания

Я собираюсь разместить небольшой сервер сокетов на локальном компьютере, и я хотел бы знать, какую пропускную способность он будет использовать. В большинстве дней к нему одновременно подключается не более 50 клиентов, но один или два раза в неделю он может иметь до 5000+ клиентов одновременно. Тем не менее, единственные отправленные сообщения будут случайным одиночным сообщением для всех подключенных клиентов одновременно без каких-либо дополнительных данных или чего-либо еще.

Приведет ли сервер к значительному падению производительности компьютера, на котором он размещен, или вообще снизит скорость моего интернета?

Сервер.js:

var app = require('http').createServer(handler)
   , io = require('socket.io').listen(app)
   , fs = require('fs')

 app.listen(8001);

function handler (req, res) {
fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.sockets.on('connection', function (socket) {
  socket.on('SendDefault', function(data) {
    socket.broadcast.emit('GetDefault');
  });
});

Клиент.js:

setTimeout( function( ){ 
  socket = io.connect('[IP Address]:8001');
  socket.on('GetDefault', function(data) {
    DoStuff( );
  );
} ); }, 10000 );

person Joe Boris    schedule 20.09.2013    source источник
comment
См. также: stackoverflow.com/a/12978658/201952   -  person josh3736    schedule 20.09.2013


Ответы (2)


Объем пропускной способности будет сильно зависеть от объема данных, которые вы собираетесь отправить с сервера, и от того, сколько данных отправит клиент. Использование полосы пропускания также будет зависеть от того, какой транспорт Socket.IO вы используете, и от интервала пульсации вашего приложения.

Влияние приложения на производительность также зависит от типа приложения, которое вы используете, и возможностей производительности вашего компьютера и/или сети. Однако более 5000 клиентов окажут значительное влияние на производительность независимо от возможностей вашего компьютера, если только вы не масштабируете приложение на несколько ядер.

Я провел некоторые измерения, используя прокси. Вот результаты:

Отправлено от клиента: socket.emit(event, args)

  • Если event и args не указаны, на сервер отправляется 12 байт.
  • Если args опущено, но указано event, общий размер составляет 22 байта, а длина event.
  • Если указаны args и event, применяются те же правила, но результаты могут различаться в зависимости от типа данных args.

Отправка с сервера: тот же формат, что и от клиента

  • Если event и args не указаны, клиенту отправляется 8 байт.
  • Если args опущено, но предоставлено event, общий размер составляет 17 байтов, а длина event.
  • Если указаны args и event, применяются те же правила, но результаты могут различаться в зависимости от типа данных args.

Пульс между сервером и клиентом: каждые 25 секунд для каждого клиента.

  • 5 байт от сервера
  • 9 байт ответа клиента

Квитирование: один раз для каждого клиента.

  • 216 байт от сервера
  • 431 байт ответа от клиента
  • 129 байт следуют от сервера

Таким образом, при нагрузке более 5000 клиентов ожидайте не менее 3,7 МБ для квитирования, 3 КБ/с для тактов и не менее 107 КБ пропускной способности для socket.emit(). Это не точные цифры, так как клиенты могут терять данные, прерывать соединения, нуждаться в повторном подключении и т. д.

В конечном счете, ваша сеть, вероятно, выдержит, но основной проблемой должно быть количество одновременных подключений, которые ваша сеть должна будет обрабатывать. Многие одновременные соединения также могут нагружать ЦП, поэтому вам следует подумать о кластеризации между ядрами. Также имейте в виду количество тактовых импульсов, которые придется обрабатывать серверу Socket.IO. При 50 одновременных пользователях это в среднем 2 пульса в секунду. При 5000+ одновременных пользователях это 200+ сердечных сокращений в секунду, что, как я полагаю, требует больше ресурсов ЦП, чем сети (2,8 КБ/с).

person hexacyanide    schedule 20.09.2013
comment
Что ж, я собираюсь отправить один пакет на сервер, а затем сразу же отправить один пакет каждому клиенту. И это будет происходить, вероятно, только один-три раза в день. Я не добавляю никаких данных в пакет, поэтому я предполагаю, что это наименьший возможный объем данных - что бы это ни было. - person Joe Boris; 20.09.2013
comment
Если событие и аргументы не указаны, на сервер отправляется 12 байт. Подождите, разве здесь не будут доминировать накладные расходы Ethernet/IP/TCP? Вы ожидаете не менее 64 байтов для одного кадра Ethernet. - person Randomblue; 30.01.2015
comment
Да вы правы. В своих расчетах я не учитывал ничего ниже прикладного уровня. - person hexacyanide; 30.01.2015

Веб-сокеты могут оставаться открытыми в течение очень долгого времени, поэтому обработка большого количества одновременных подключений обычно означает, что вам потребуется масштабировать эту службу, чтобы приспособиться к возросшей нагрузке. Это то же самое почти для любой технологии, но обычно существует ограничение на максимальное количество открытых подключений, которые сервер может обработать, прежде чем дела быстро пойдут на спад. Если у вас, вероятно, будут такие пики трафика, я бы рассмотрел возможность поиска стороннего сервиса, такого как pusher или kaazing (отказ от ответственности: я еще не пробовал).

Вы задали довольно расплывчатый вопрос (мы ничего не знаем о вашем приложении, архитектуре и т. д. — только ожидаемый трафик), но, надеюсь, это поможет указать вам правильное направление. При этом ... исходя из вашего варианта использования (передача одного или двух небольших сообщений, время от времени), моя интуиция подсказывает мне, что WebSockets - не подходящая технология для вас.

(Обратите внимание, что пропускная способность, вероятно, не должна вызывать беспокойства - вообще говоря, если вы будете отправлять много сообщений через WebSockets по сравнению с REST, вы будете отправлять меньше данных из-за заголовков, файлов cookie и т. д.)

person Jesse Fulton    schedule 20.09.2013