Как ускорить node js

Тонкости Javascript/Node.js. Увеличиваем производительность в десятки раз

Вступление

Появилась необходимость обмениваться сообщениями между сервером и клиентом в бинарном виде, но в формате JSON в конечном итоге. Начал я гуглить, какие существуют библиотеки упаковки в бинарный вид. Пересмотрел немало: MesssagePack, Bson, protobuf, capnproto.org и другие. Но эти все библиотеки позволяют паковать и распаковывать готовые бинарные пакеты. Не очень копался, возможно ли делать парсер входящего трафика по кускам. Но суть не в этом. С такой задачей никогда не сталкивался и решил поиграться с нодой и сделать свой. Куда же без костылей и велосипедов? И вот с какими особенностями Node.js я столкнулся…

Написал я пакер и запустил…

4300. Удивился… Почему так долго? В то время, как код:

350. Не понял. Начал копать свой код и искать, где же много ресурсов используется. И нашел.

Выдает 1908. Вы скажете: да это не много на 1000000 повторений. А если я скажу, что много? Выполним такой код:

Выдает 16. Мои коллеги тоже возмутились, но и заметили, что функция же создается динамически и сразу уничтожается, ты ее вынес и нет такой нагрузки. Из эксперимента вывод: динамические фунции не кешируюся в бинарном виде. Я согласился и возразил: да, но нет ни переменных в SCOPE ничего используемого внутри нее. Похоже, движок гугла всегда копирует SCOPE.

Ок. Провел оптимизацию этой фунциональности и запустил… и все равно. Выдал

3000. Опять удивился. И снова полез копать… и обнаружил уже другой прикол.

Выдал 34. Теперь, допустим, нам надо внутри abc создать Array:

Выдал 1826. Смеркалось… А если нам надо 3 массива?

Выдал 5302! Вот это приколы. Казалось, SCOPE мы не используем, а создание пустого массива должно занимать вообще копейки. Не тут то было.

Думаю… А заменю-ка я на объекты. Результат получше, но не намного. Выдал 1071.

А теперь фокус. Многие скажут: ты же опять выносишь функцию. Да. Но фокус в другом.

Многие заметят и скажут: будет такое же время. А не тут то было. Выдал 25. Хотя массивы создавались столько же раз. Делаем вывод: создание массивов в динамической функции тратит много ресурсов. Вопрос: почему?

Теперь вернемся к первой проблеме. Но с другой стороны. Вынесем Array:

И я был прав. Выдал 58. С выносом всей фунции выдавал 16. Т.е. создание функции не особо ресурсоемкий процесс. Также опровергаем прошлый вывод:

бинарный код функций все же кешируется в памяти. А создание объектов в динамической функции занимает много времени.

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

Источник

Оптимизация node.js приложения

Дано: старое http node.js приложение и возросшая нагрузка на него.

Стандартные решения проблемы: докинуть серверов, все переписать с 0, оптимизировать уже написанное.

Давайте попробуем пойти путем оптимизации и разобраться, как можно найти и улучшить слабые места приложения. А быть может ускориться не трогая ни строчки кода 🙂

Всех заинтересованных добро пожаловать под кат!

Для начала определимся с методикой тестирования производительности. Нас будет интересовать количество обслуженных запросов за 1 секунду: rps.

Запускать будем приложение в режиме 1 воркера (1 процесса), замеряя производительность старого кода и кода с оптимизациями — абсолютная производительность не важна, важна сравнительная производительность.

В типичном приложении с множествами разных роутов логично сначала найти самые загруженные запросы, на обработку которых тратится большая часть времени. Утилы вида request-log-analizer или множество подобных позволят извлечь эту информацию из логов.

С другой стороны, можно взять реальный список запросов и пулять их все (например с помощью yandex-tank-а) — получим достоверный профиль нагрузки.

Но делая множество итераций оптимизации кода, куда удобнее использовать более простой и быстрый инструмент и один конкретный тип запросов (а после оптимизации одного запроса изучать следующий, и т.д.). Мой выбор — wrk. Тем более что в моем случае количество роутов не велико — проверить все по одному не сложно.

Сразу надо оговорится, что в плане блокирующих запросов, ожидания БД и т.п. приложение уже оптимизировано, все упирается в cpu: при тестах воркер потребляет 100% cpu.

На продашен серверах используется node.js версии 6 — с неё и начнем:

Пробуем на 8й ноде:
Requests/sec: 2308
10я нода:
Requests/sec: 2590

Разница очевидна. Ключевую роль тут играет обновление версии v8 — множество плохо оптимизирующегося v8 кода осталось в прошлом. И чтобы не бороться с ветряными мельницами исчезнувшими в node.js v8 — лучше сразу обновиться, а потом уже заниматься оптимизацией кода.

Примерно так выглядит flamegraph тестируемого кода до оптимизаций:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js
Внизу фильтры, оставляем app, deps — только код приложения и сторонних модулей.

Чем шире полоска — тем больше времени потрачено на выполнения этой функции (включая вложенные вызовы).

Разбираться будем с центральной, самой большой частью.

В первую очередь подсвечиваем неоптимизированные функции. У меня в приложении таких нашлось немного.

Далее, верхние функции — типичные кандидаты на оптимизацию. Остальные же функции выстроились горкой с относительно равномерными ступеньками — каждая функция вкладывает небольшую долю задержек, явного лидера нет.

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

Удобное следствие такого подхода: можно видеть rps в идеальных условиях (при работающей только одной стартовой функцией rps близок к максимальному rps-у hellow world node.js приложения), и при дальнейшем перемещении заглушки-ответа вглубь приложения наблюдать вклад исследуемой функции в падение производительности в rps-ах.

Итак, оставляем только стартовую функцию, получаем:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

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

Переходим к следующей функции:

Requests/sec: 16111
Ничего не изменилось — погружаемся дальше:
Requests/sec: 13330
Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Наш клиент! Видно что задействованная функция getByUrl занимает значимую часть стартовой функции — что хорошо коррелирует с проседанием rps.

Смотрим внимательно что в ней происходит (включаем core, v8):

Много чего происходит… курим код, оптимизируем:

В данном случае простой for значительно быстрее for..in

Получаем Requests/sec: 16015

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Визуально функция «сдулась» и занимает значительно меньшую долю от стартовой функции.
В детальной информации по функции так же все значительно упростилось:

Идем дальше, к следующей функции

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

В этой функции много array функций и, несмотря на существенное ускорение в последних версиях node.js, они все еще медленней простых циклов: меняем [].map и filter. на обычный for и получаем

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

И так раз за разом, для каждой следующей функции.

Еще несколько пригодившихся оптимизаций: для хешей с динамически изменяемым набором ключей new Map() может быть на 40% быстрее обычного <>;

Math.round(el*100)/100 в 2 раза быстрее чем toFixed(2).

В flamegraph-е для core и v8 функций можно увидеть как и малопонятные записи, так и вполне говорящие StringPrototypeSplit или v8::internal::Runtime_StringToNumber, и, если это значимая часть выполнения кода, попытаться оптимизировать, например просто переписать код, не выполняющий эти операции.

Например, замена split на несколько вызовов indexOf и substring может давать двойной выигрыш в производительности.

Отдельная большая и сложная тема — jit оптимизация, а вернее деоптимизированные функции.
При наличии большой доли таких функций надо будет разбираться и с ними.

Например, строчки вида

deoptimizing (DEOPT soft): begin 0x2bcf38b2d079 = 10? val: ‘0’+val;

return (val >= 10? »: ‘0’)+val;

Для старого v8 движка есть достаточно много информации по причинам и способах борьбы с деоптимизацией функций:

Но многие из проблем уже не актуальны для нового v8.

Так или иначе, после всех оптимизаций удалось получить Requests/sec: 9971, т.е. ускорится примерно в 2 раза за счет перехода на свежую версию node.js, и еще в 4 раза за счет оптимизации кода.

Надеюсь, этот опыт будет полезен кому-нибудь еще.

Источник

Делаем Node.js быстрым: инструменты, техники и советы для создания эффективных серверов на Node.js Часть первая

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Node очень универсальная платформа, однако именно создание сетевых процессов одно из основных её применений. В этой статье мы сосредоточимся на профилировании наиболее распространённого из них: веб-сервера HTTP.

Если вы достаточно долго работали с Node.js, тогда вы наверняка сталкивались с неожиданными проблемами быстродействия. JavaScript событийный, асинхронный язык. Это затрудняет рассуждения о производительности, позже мы в этом убедимся. Растущая популярность Node.js выявила необходимость в инструментах, методах и мышлении, подходящих для ограничений серверного JavaScript.

Если говорить о производительности, то, что работает в браузере, не всегда подходит для Node.js. Так, как же нам убедиться, что реализация Node.js быстра и соответствует задаче? Давайте рассмотрим практический пример.

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

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Apache Bench (ab) и wrk2 также хорошие инструменты для подобных целей, но AutoCannon написан на Node. Он обеспечивает аналогичную (или иногда большую) нагрузку и очень прост в установке на Windows, Linux и Mac OS X.

После того, как мы измерили базовую производительность, и решили, что процесс можно ускорить, нам понадобится какой-то способ диагностики проблем с процессом. Отличным инструментом для диагностики различных проблем производительности является Node Clinic, который также может быть установлен с помощью npm:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Эта команда установит пакет инструментов. А мы в примере будем использовать Clinic Doctor и Clinic Flame (wrapper 0x).

Примечание: для этого практического примера нам понадобится Node 8.11.2 или выше.

index.js файл для нашего сервера выглядит так:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Этот типичный сервер для обслуживания динамического контента, который кэшируется на стороне клиента. Это достигается с помощью etagger middleware, который вычисляет ETag загаловок для последнего состояния содержимого.

Файл util.js предоставляет исполняющие части, которые обычно используются в подобных сценариях, функцию для извлечения релевантного контента из бэкенда, etag middleware и функцию timestamp, которая выдаёт тайм метки поминутно:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Однако этот код не лучший вариант для практики! В этом коде есть несколько проблем, мы найдем их по ходу измерений и профилирования приложения.

Профилирование

Чтобы начать профилировать, нам нужны 2 терминала, один для запуска приложения, а другой для тестирования нагрузкой.

На одном терминале, из папки app мы можем запустить:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

На другом терминале профилировать его так:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Это откроет 100 одновременных соединений и бомбардирует сервер запросами в течение десяти секунд.

Результаты должны быть примерно такими (запуск теста 10сек @ http://localhost:3000/seed/v1 –100 соединений):

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

231 запрос за 10 секунд, 2,4 МБ чтения

Результаты будут отличаться в зависимости от машины. Однако, учитывая, что “Hello World” Node.js сервер легко обработает и тридцать тысяч запросов в секунду на этой машине, 23 запроса в секунду со средней задержкой, превышающей 3 секунды — это печально.

Диагностируем

Обнаруживаем проблемные места

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Это создаст HTML-файл, который автоматически откроется в нашем браузере после завершения профилирования.

Результаты должны выглядеть примерно так:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node jsРезультаты Clinic Doctor

«Доктор» говорит нам, что у нас, вероятно, была проблема с циклом событий (Event Loop).

Вместе с сообщением в верхней части UI, мы также можем видеть, что диаграмма Event Loop красного цвета, и показывает постоянно увеличивающуюся задержку. Прежде чем мы углубимся в значение этого показателя, давайте сначала разберемся какой эффект оказывает эта проблем на остальные метрики.

Мы видим, что процессор стабильно находится на уровне или выше 100%, пока процесс упорно обрабатывает запросы из очереди. JavaScript движок Node.js (V8) в этом случае фактически использует два ядра процессора, потому что машина многоядерная и V8 использует два потока. Один для цикла обработки событий, а другой для «сбора мусора». Там, где мы видим пики нагрузки вплоть до 120% — это процесс собирает объекты, связанные с обработанными запросами.

Мы видим эту корреляцию на графике Memory. Сплошная линия на диаграмме Memory — это метрика Heap Used. Каждый раз, когда есть всплеск ЦП, мы видим проседание Heap Used, это показывает, что память освобождается.

Если щелкнуть панель Recommendations в нижней части экрана, мы увидим примерно следующее:

Временный меры

Анализ основных причин, серьезных проблем с производительностью, может занять некоторое время. В случае уже развернутого проекта стоит добавить защиту от перегрузки на серверы или службы. Идея защиты от перегрузки состоит в том, чтобы контролировать задержку Event Loop (помимо прочего) и отвечать ошибкой “503 Service Unavailable”, если порог пройден. Это позволяет балансировщику нагрузки переключаться на другие инстансы или в худшем случае пользователям придется обновлять страницу. Модуль защиты от перегрузки может обеспечить это с минимальным оверхедом для Express, Koa, и Restify. Фреймфорк Hapi может обеспечить такую же защиту с помощью настройки конфигурации.

В продолжении статьи, после диагностики производительности с помощью Clinic Doctor, мы приступим к анализу метрик используя flame graph. Найдём проблемные места в нашем коде и начнём его исправлять.

Источник

Ускоряем node.js: нативные модули и CUDA

Иногда разработчики различных веб-проектов сталкиваются с необходимостью обработки больших объемов данных или использованием ресурсозатратного алгоритма. Старые инструменты уже не дают необходимой производительности, приходится арендовать/покупать дополнительные вычислительные мощности, что подталкивает к мысли переписать медленные участки кода на C++ или других быстрых языках.

В этой статье я расскажу о том, как можно попробовать ускорить работу Node.JS (который сам по себе считается довольно быстрым). Речь пойдет о нативных расширениях, написанных с помощью C++.

Коротко о расширениях

Итак, у вас имеется веб-сервер на Node.JS и вам поступила некая задача с ресурсозатратным алгоритмом. Для выполнения задачи было принято решение написать модуль на C++. Теперь нам надо разобраться с тем, что же это такое — нативное расширение.

Архитектура Node.JS позволяет подключать модули, упакованные в библиотеки. Для этих библиотек создаются js-обертки, с помощью которых вы можете вызывать функции этих модулей прямо из js-кода вашего сервера. Многие стандартные модули Node.JS написаны на C++, однако это не мешает пользоваться ими с таким удобством, как будто они были бы написаны на самом javascript’e. Вы можете передавать в свое расширение любые параметры, отлавливать исключения, выполнять любой код и возвращать обработанные данные обратно.
По ходу статьи мы разберемся в том, как создавать нативные расширения и проведем несколько тестов производительности. Для тестов возьмем не сложный, но ресурсозатратный алгоритм, который выполним на js и на C++. Например — вычислим двойной интеграл.

Что считать?

Возьмем функцию:
Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js
Эта функция задает следующую поверхность:
Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js
Для нахождения двойного интеграла нам необходимо найти объем фигуры, ограниченной данной поверхностью. Для этого разобьем фигуру на множество параллелепипедов, с высотой, равной значению функции. Сумма их объемов даст нам объем всей фигуры и численное значение самого интеграла. Для нахождения объема каждого параллелепипеда разобьем площадь под фигурой на множество маленьких прямоугольников, затем перемножим их площади на значение нашей функции в точках на краях этих прямоугольников. Чем больше параллелепипедов, тем выше точность.
Код на js, который выполняет это интегрирование и показывает нам время выполнения:

Подготовка к написанию расширения

Нативное расширение

Все настроено, приступаем к написанию кода.

Добавляем этот код к уже готовому проекту на Node.JS, вызываем функции, сравниваем:

Получаем результат:
JS result = 127.99999736028109
JS time = 127
Native result = 127.999997
Native time = 103

Разница минимальна. Увеличим количество итераций по осям в 8 раз. Получим следующие результаты:

JS result = 127.99999995875444
JS time = 6952
Native result = 128.000000
Native time = 6658

Выводы

Результат удивляет. Мы не получили практически никакого выигрыша. Результат на Node.JS получается почти точно таким же, какой получается на чистом С++. Мы догадывались что V8 быстрый движок, но чтоб настолько… Да, даже чисто математические операции можно писать на чистом js. Потеряем мы от этого немного, если вообще что-то потеряем. Чтобы получить выигрыш от нативного расширения мы должны использовать низкоуровневую оптимизацию. Но это будет уже слишком. Выигрыш в производительности от нативного модуля далеко не всегда окупит затраты на написание сишного или даже ассемблерного кода. Что же делать? Первое что приходит на ум — использование openmp или нативных потоков, для параллельного решения задачи. Это ускорит решение каждой отдельно взятой задачи, но не увеличит количество решаемых задач в единицу времени. Так что такое решение подойдет не каждому. Нагрузка на сервер не снизится. Возможно мы так же получим выигрыш при работе с большим объемом памяти — у Node.JS все таки будут дополнительные накладные расходы и общий занимаемый объем памяти будет больше. Но память сейчас далеко не так критична, как процессорное время. Какие выводы мы можем сделать из данного исследования?

We need to go deeper

А давайте-ка все таки попробуем ускорить работу нашего кода? Раз у нас есть доступ из нативного расширения к чему угодно, то есть доступ и к видеокарте. Используем CUDA!

Напишем обработчик на js:

Запустим тестирование на следующих данных:

JS result = 127.99999736028109
JS time = 119
Native result = 127.999997
Native time = 122
CUDA result = 127.999997
CUDA time = 17

Как мы видим, обработчик на видеокарте уже показывает сильный отрыв. И это при том, что результаты работы каждого потока видеокарты я суммировал на CPU. Если написать алгоритм, полностью работающий на GPU, без использования центрального процессора, то выигрыш в производительности будет еще ощутимее.
Протестируем на следующих данных:

Получим результат:
JS result = 127.99999998968899
JS time = 25401
Native result = 128.000000
Native time = 28405
CUDA result = 128.000000
CUDA time = 3568

Источник

Делаем Node.js быстрым: инструменты, техники и советы для создания эффективных серверов на Node.js Часть третья.

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Aug 31, 2018 · 4 min read

Оптимизируем

Теперь, когда мы обнаружили проблемные области, давайте посмотрим, можем ли мы сделать сервер быстрее.

Лёгкий и быстрый способ

Давайте вернем код слушателя server.on (вместо пустой функции) и используем правильное имя для проверки условия. Наша функция etagger выглядит вот так:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Профилируем снова, чтобы проверить наши исправления. Запустите сервер на одном терминале:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Затем профилируем с AutoCannon:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Результат должен улучшится примерно в 200 раз. (запуск теста 10сек @ http://localhost:3000/seed/v1 — 100 подключений):

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Важно сбалансироват ь потенциальное снижение стоимости сервера с затратами на разработку. Нам нужно определить, в контексте нашей ситуации, как далеко нам нужно зайти в оптимизации проекта. В противном случае, мы легко можем положить 80% усилий в 20% повышения скорости. Оправдывают ли это ограничения проекта?

В некоторых случаях было бы целесообразно достичь улучшения в 200 раз лёгким путём, потратив на это всего день. В других случаях мы, возможно, захотим сделать нашу реализацию настолько быстрой, насколько это возможно. Это действительно зависит от приоритетов проекта.

Один из способов контролировать расходы ресурсов — постановка цели. Например, улучшение в 10 раз или 4000 запросов в секунду. Имеет смысл исходить из потребностей бизнеса. Например, если затраты на сервер превышают бюджет на 100%, мы можем поставить цель улучшения в 2 раза.

Идём дальше

Если мы создадим новый flame graph нашего сервера, мы увидем что-то подобное:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Слушатель событий по-прежнему bottleneck, он всё еще занимает одну треть процессорного времени во время профилирования (ширина составляет около трети всего графика).

Какие еще улучшения можно сделать, и стоит ли вносить изменения (учитывая связанные с ними последствия)?

В оптимизированной реализации, которая, тем не менее ограничена, могут быть достигнуты следующие характеристики (запуск теста 10сек @ http://localhost:3000/seed/v1 –10 подключений):

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Улучшение в 1.6 раз это существенно, но оправданы ли усилия, изменения и нарушение кода, необходимые для достижения такого результата? Зависит от ситуации. Особенно по сравнению с 200-кратным улучшением оригинальной реализации после исправления одной ошибки.

Для достижения этого улучшения использовалась та же итеративная техника: профилирование, flame graph, анализ, debug, оптимизация. Код оптимизированного сервера можно найти здесь.

На последок, для достижения 8000 запросов/сек :

Давайте взглянем на flame graph после последних улучшений:

Как ускорить node js. Смотреть фото Как ускорить node js. Смотреть картинку Как ускорить node js. Картинка про Как ускорить node js. Фото Как ускорить node js

Предотвращение проблем с производительностью

В заключение приведу несколько рекомендаций по предотвращению проблем с производительностью перед развертыванием.

Используйте инструменты для отслеживания проблем с производительностью на этапе разработки. Они помогут отфильтровать баги, прежде чем они попадут в продакшн. Рекомендую использовать инструменты AutoCannon и Clinic (или их эквиваленты) в повседневной разработке.

Если покупаете фреймворк, разузнайте о его политике производительности. Если производительность не самая сильная сторона фреймворка, тогда важно проверить, соответствует ли он инфраструктурным практикам и бизнес-целям. Например, команда Restify явно (начиная с релиза седьмой версии) вложилась в повышение производительности библиотеки. Впрочем, если низкая стоимость и высокая скорость являются абсолютным приоритетом, рассмотрите Fastify. Его производительность на 17% выше, измерения проводил участник Restify.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *