Действия по повышению пропускной способности серверного приложения Node JS

У меня есть очень простое приложение nodejs, которое принимает данные json (приблизительно 1 КБ) через тело запроса POST. Ответ немедленно отправляется обратно клиенту, а json асинхронно отправляется в очередь Apache Kafka. Количество одновременных запросов может достигать 10000 в секунду, что мы моделируем с помощью Apache Jmeter, работающего на трех разных машинах. Цель состоит в том, чтобы достичь средней пропускной способности менее одной секунды без неудачных запросов.

На 4-ядерном компьютере приложение обрабатывает до 4015 запросов в секунду без каких-либо сбоев. Однако, поскольку целью является 10 000 запросов в секунду, мы развернули приложение узла в кластерной среде.

И кластеризация на одном компьютере, и кластеризация между двумя разными машинами (как описано здесь) были реализованы. Nginx использовался в качестве балансировщика нагрузки для циклического перебора входящих запросов между двумя экземплярами узла. Мы ожидали значительного улучшения пропускной способности (как задокументировано здесь) но результаты были наоборот. Количество успешных запросов упало примерно до 3100 запросов в секунду.

Мои вопросы:

  1. Что могло пойти не так в кластерном подходе?
  2. Это вообще правильный способ увеличить пропускную способность приложения Node?
  3. Мы также выполнили аналогичное упражнение с веб-приложением Java в контейнере Tomcat, и оно выполнило, как и ожидалось, 4000 запросов с одним экземпляром и около 5000 успешных запросов в кластере с двумя экземплярами. Это противоречит нашему убеждению, что nodejs работает лучше, чем Tomcat. Tomcat в целом лучше из-за своей модели потока для каждого запроса?

Заранее большое спасибо.


person Ashok    schedule 27.06.2017    source источник
comment
Кластеризация, как правило, является правильным подходом, но поможет ли она, зависит от того, где находится узкое место. Вам нужно будет провести некоторые измерения и несколько экспериментов, чтобы определить это. Если вы привязаны к ЦП и работаете на многоядерном компьютере, то кластеризация должна значительно помочь. Интересно, является ли ваше узкое место чем-то помимо ЦП, например, сетью или другим общим вводом-выводом или даже Nginx? Если это так, вам нужно исправить это, прежде чем вы увидите преимущества кластеризации.   -  person jfriend00    schedule 27.06.2017
comment
В целом, tomcat лучше из-за его модели потока на запрос? Нет. Это не очень хорошее обобщение. Если вы привязаны к процессору, вам может помочь многопоточность (как и кластеризация с помощью nodejs). Но если вы привязаны к вводу-выводу, то потоки часто обходятся дороже, чем асинхронный ввод-вывод, такой как nodejs, из-за накладных расходов на ресурсы самих потоков и накладных расходов на переключение контекста между потоками.   -  person jfriend00    schedule 27.06.2017
comment
@jfriend00 Спасибо за участие. Я попытаюсь сделать это шаг за шагом, чтобы увидеть изменение пропускной способности. Думаю, это должно дать нам подсказку, где находится узкое место. Я забыл упомянуть, что для http мы используем экспресс вместо собственного http, предоставляемого узлом. Надеюсь, это не приведет к накладным расходам на обработку запросов? Проверим, если не будет прорыва в других областях.   -  person Ashok    schedule 28.06.2017
comment
@ jfriend00 Я хотел бы принять ваш ответ в качестве ответа, но это комментарий. можно ли это сделать еще как-то?   -  person Ashok    schedule 28.06.2017


Ответы (2)


По вашему запросу я добавлю свои комментарии в ответ:

Кластеризация, как правило, является правильным подходом, но поможет ли она, зависит от того, где находится узкое место. Вам нужно будет провести некоторые измерения и несколько экспериментов, чтобы определить это. Если вы привязаны к ЦП и работаете на многоядерном компьютере, то кластеризация должна значительно помочь. Интересно, является ли ваше узкое место чем-то помимо ЦП, например, сетью или другим общим вводом-выводом или даже Nginx? Если это так, вам нужно исправить это, прежде чем вы увидите преимущества кластеризации.

Tomcat в целом лучше из-за своей модели потока для каждого запроса?

Нет. Это не очень хорошее обобщение. Если вы привязаны к процессору, вам может помочь многопоточность (как и кластеризация с помощью nodejs). Но если вы привязаны к вводу-выводу, то потоки часто обходятся дороже, чем асинхронный ввод-вывод, такой как nodejs, из-за накладных расходов на ресурсы самих потоков и накладных расходов на переключение контекста между потоками. Многие приложения привязаны к вводу-выводу, что является одной из причин, по которой node.js может быть очень хорошим выбором для проектирования серверов.

Я забыл упомянуть, что для http мы используем экспресс вместо собственного http, предоставляемого узлом. Надеюсь, это не приведет к накладным расходам на обработку запросов?

Express очень эффективен и не должен быть источником каких-либо проблем.

person jfriend00    schedule 28.06.2017
comment
Большое спасибо, я отпишусь о наших выводах после завершения упражнения. - person Ashok; 29.06.2017

Как сказал jfriend, вам нужно найти узкие места, одна вещь, которую вы можете попробовать, - это уменьшить полосу пропускания/пропускную способность, используя сокеты для передачи json и особенно эту библиотеку https://github.com/uNetworking/uWebSockets. Основная причина этого заключается в том, что HTTP-запрос значительно тяжелее, чем соединение через сокет.

Хороший пример: https://webcheerz.com/one-million-requests-per-second-node-js/

наконец, вы также можете сжать json через (http gzip) или сторонний модуль.

работай над весом ^^

Надеюсь, поможет!

person Sam    schedule 27.06.2017
comment
Спасибо за ссылку на веб-сокеты. На самом деле мы рассматриваем MQTT для наших целей. Вариант сжатия тоже проверю. - person Ashok; 28.06.2017