Глава 3 - Дополнительные передовые методы повышения эффективности и производительности

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

Веб-процессы и рабочие процессы

Как вы, вероятно, знаете, Node.js на практике является однопоточным, поэтому один экземпляр процесса может выполнять только одно действие за раз. В течение жизненного цикла веб-приложения выполняется множество различных задач: управление вызовами API, чтение / запись в БД, обмен данными с внешними сетевыми службами, выполнение некоторой неизбежной работы с интенсивным использованием ЦП и т. Д.

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

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

Веб-процесс предназначен в основном для управления входящими сетевыми вызовами и для их максимально быстрой отправки. Каждый раз, когда необходимо выполнить неблокирующую задачу, например, отправить электронное письмо / уведомление, написать журнал, выполнить триггерное действие, результат которого не требуется для ответа на вызов API, веб-процесс делегирует действие рабочему. .

Связь между веб-процессами и рабочими может быть реализована по-разному. Распространенным и эффективным решением является очередь с приоритетом, подобная той, которая реализована в Kue, описанная в следующем абзаце.

Одним из больших преимуществ этого подхода является возможность независимо масштабировать веб-процессы и рабочие процессы на одной или на разных машинах.

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

Куэ

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

Kue - это обычная библиотека очередей для Node.js, она основана на Redis и позволяет вам одинаково запускать коммуникационные процессы, запускаемые на одной или на разных машинах.

Любой процесс может создать задание и поместить его в очередь, а затем рабочие процессы настроены на выбор этих заданий и их выполнение. Для каждого задания может быть предоставлено множество опций, таких как приоритет, TTL, задержка и т. Д.

Чем больше рабочих процессов вы запускаете, тем больше у вас параллельной пропускной способности для выполнения этих заданий.

Cron

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

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

Более удобный способ добиться того же результата - использовать модуль cron, доступный в NPM. Он позволяет вам определять задания cron внутри кода Node.js, делая его независимым от конфигурации ОС.

В соответствии с описанным выше шаблоном web / worker рабочий процесс может создать cron, который вызывает функцию, периодически помещающую новое задание в очередь.

Использование очереди делает ее более чистой и позволяет использовать все функции, предлагаемые kue, такие как приоритет, повторные попытки и т. Д.

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

Чтобы решить эту проблему, необходимо определить один рабочий процесс, который будет выполнять операции cron.

Выборы лидера и cron-кластер

Такая проблема известна как выборы лидера, и для этого конкретного сценария существует пакет NPM, который решает эту задачу за нас, называемый cron-cluster.

Он предоставляет тот же API, что и модуль cron, но во время настройки ему требуется соединение redis, используемое для связи с другими процессами и выполнения алгоритма выбора лидера.

Используя redis как единый источник истины, весь процесс будет согласовывать, кто будет выполнять cron, и только одна копия заданий будет помещена в очередь. После этого все рабочие процессы смогут выполнять задания в обычном режиме.

Кеширование вызовов API

Кеширование на стороне сервера - это распространенный способ повышения производительности и реактивности ваших вызовов API, но это очень обширная тема с множеством возможных реализаций.

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

Самый сложный аспект, который следует учитывать при кэшировании, - это его недействительность. Быстрое и грязное решение учитывает только время, поэтому значения в кеше сбрасываются после фиксированного TTL, а обратная сторона - ждать следующего сброса, чтобы увидеть обновления в ответах.

Если у вас есть больше времени, было бы лучше реализовать аннулирование на уровне приложения, вручную очищая записи в кэше redis при изменении значений в БД.

Выводы

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

Следите за другими статьями о вертикальных темах на Node.js и DevOps!

Если вам нравится эта статья, хлопайте сколько угодно!