javascript

Масштабирование NodeJS приложений, теория и практика

  • воскресенье, 29 января 2023 г. в 00:40:45
https://habr.com/ru/post/713420/
  • JavaScript
  • Nginx
  • Node.JS
  • API


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

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

С другой стороны, вертикальное масштабирование предполагает увеличение ресурсов одной машины для обработки возросшей нагрузки. Это можно сделать, добавив на машину больше памяти, ЦП или хранилища. Этот метод менее сложен, чем горизонтальное масштабирование, и часто используется в качестве начальной стратегии масштабирования. Однако у него есть ограничения, так как существует физический предел количества ресурсов, которые можно добавить на одну машину.

Reverse-proxy или Обратный прокси

Другой подход к масштабированию приложений Node.js — использование обратного прокси-сервера. Обратный прокси, например Nginx или HAProxy, перед приложением Node.js. Обратный прокси-сервер может выполнять такие задачи, как балансировка нагрузки, терминация SSL и кэширование, позволяя приложению Node.js сосредоточиться на бизнес-логике. Кроме того, использование обратного прокси-сервера позволяет более детально контролировать доступ приложения к Интернету и может помочь повысить безопасность и производительность, обратный прокси-сервер находится перед серверами приложений и обрабатывает входящий трафик, перенаправляя запросы на соответствующий сервер. Это позволяет более эффективно использовать ресурсы, а также лучше контролировать входящий трафик. Кроме того, обратные прокси-серверы могут использоваться для реализации шифрования SSL/TLS, что важно для защиты конфиденциальных данных.

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

Кластеризация

Кластеризация — еще один метод, который можно использовать для масштабирования приложений Node.js, например с помощью утилиты как PM2. Кластеризация позволяет нескольким экземплярам приложения работать одновременно, каждый в своем собственном процессе. Это позволяет приложению использовать преимущества нескольких процессоров, повышая производительность.

Хочу примеры!

Хорошо, давайте приведу примеры горизонтального масштабирования с помощью PM2.
Чтобы горизонтально масштабировать приложение NodeJS с помощью PM2, вы можете использовать функцию режима кластера PM2. Вот основные шаги по его настройке:

1. Установите PM2 глобально в вашей системе с помощью npm:
npm install pm2 -g
2. Запустите приложение NodeJS в кластерном режиме, выполнив следующую команду:
pm2 start app.js -i max (замените «app.js» именем основного файла приложения)
Эта команда запустит максимальное количество процессов в соответствии с количеством доступных ядер ЦП.
3. Вы можете проверить состояние своего кластера, запустив pm2 list
4. Чтобы увеличить или уменьшить количество процессов, вы можете использовать команду масштабирования pm2. Например, чтобы масштабировать до 4 процессов, вы должны запустить приложение масштабирования pm2 4.
5. Чтобы убедиться, что приложение перезапускается после перезагрузки сервера, вы можете использовать команду pm2 save, которая сохраняет текущий список процессов и перезапускает их при перезагрузке.
6. Вы можете отслеживать использование ресурсов и производительность приложения с помощью встроенных инструментов мониторинга и визуализации PM2, таких как pm2 monit и pm2 show.

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

Масштабирование приложения Node.js с обратным прокси

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

Вот пример того, как настроить приложение Node.js с Nginx в качестве обратного прокси-сервера и использовать балансировку нагрузки IP-хэша:

1. Запустите несколько экземпляров приложения Node.js на разных портах (например, 3000, 3001, 3002).
2. Настройте Nginx для прослушивания определенного порта (например, 80) и пересылки входящих запросов экземплярам приложения Node.js.

http {
    upstream nodejs_app {
        ip_hash;
        server localhost:3000;
        server localhost:3001;
        server localhost:3002;
    }
    server {
        listen 80;
        server_name example.com;
    
        location / {
            proxy_pass http://nodejs_app;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
}

В этом примере Nginx прослушивает порт 80 и перенаправляет входящие запросы в «восходящий» блок, который определяет экземпляры приложения Node.js. Директива «ip_hash» указывает Nginx использовать балансировку нагрузки IP‑хэша, которая назначает каждого клиента определенному серверу на основе его IP‑адреса. Это гарантирует, что запросы от одного и того же клиента всегда будут отправляться на один и тот же сервер, что полезно для сохранения состояния.

Вы также можете использовать другие алгоритмы балансировки нагрузки, такие как циклический перебор или наименьший_конн (least_conn). А также используйте другое программное обеспечение, такое как HAProxy, для балансировки нагрузки перед Nginx. Это базовый пример, в реальных сценариях вам может потребоваться рассмотреть другие аспекты, такие как автоматическое масштабирование в зависимости от трафика, мониторинга и других факторов.

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

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

На этом мы заканчиваем нашу статью, надеюсь было интересно! :-)

Оставляйте комментарии, ставьте лайки, делитесь своим опытом масштабирования NodeJS приложений.