Лучшие практики для высокопроизводительных и масштабируемых приложений Node.js [Часть 1/3]

Node.js сервер балансировки нагрузки Программа перевода самородков

В трех статьях этой серии мы рассмотрим некоторые передовые методы разработки серверных веб-приложений Node.js.

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

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

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

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

Среди указанных операций есть некоторыеРекомендуемая практикаБудет рассмотрено в третьем посте, когда вы масштабируетесь до N процессов/машин и не собираетесь запускать N раз, например, разделить API и рабочие процессы, использовать приоритетные очереди, управлять периодическими заданиями, такими как процессы cron.

Глава 1. Горизонтальное масштабирование приложения Node.js

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

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

Несколько процессов на одной машине

Обычный способ увеличить пропускную способность приложения — создать процесс для каждого ядра компьютера. Таким образом, мы можем продолжать генерировать и распараллеливать «одновременное» управление запросами, которое хорошо работает в Node.js (см. «Управляемый событиями неблокирующий ввод-вывод»).

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

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

Описанные ниже стратегии являются стандартными для Node.js.кластерный режими автоматический, более высокий уровеньКластер PM2Функции.

Собственный кластерный режим

Локальный кластер Node.js — это основной способ масштабирования приложения Node на одном компьютере (node.is.org/API/cluster…). Экземпляр вашего процесса (называемый «главным») — это экземпляр, ответственный за порождение других дочерних процессов (называемых «рабочими»), по одному на каждый процесс, выполняющий приложение. Входящие запросы распределяются в соответствии с политиками циклического перебора всех рабочих процессов, и доступ к ним осуществляется через один и тот же порт.

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

Следующий пример взят из официальной документации:

const cluster = require(‘cluster’);
const http = require(‘http’);
const numCPUs = require(‘os’).cpus().length;

if (cluster.isMaster) {
  
 console.log(`Master ${process.pid} is running`);
  
 // Fork workers.
 for (let i = 0; i < numCPUs; i++) {
  cluster.fork();
 }
  
 cluster.on(‘exit’, (worker, code, signal) => {
  console.log(`worker ${worker.process.pid} died`);
 });
  
} else {
  
 // Workers can share any TCP connection
 // In this case it is an HTTP server
 http.createServer((req, res) => {
  res.writeHead(200);
  res.end(‘hello world\n’);
 }).listen(8000);
  
 console.log(`Worker ${process.pid} started`);
 
}

Кластерный режим PM2

Если вы используете PM2 в качестве диспетчера процессов (что я вам и рекомендую), есть волшебная функция кластеризации, которая позволяет масштабировать процессы по всем ядрам, не беспокоясь о кластеризации. Демон PM2 будет выступать в роли «мастера» и порождать N дочерних процессов в качестве рабочих, нагрузка на которые затем распределяется с использованием алгоритма циклического перебора.

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

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

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

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

Балансировка сетевой нагрузки на несколько серверов

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

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

Серверы балансировки сетевой нагрузки можно развертывать по-разному. Если вы используете AWS для настройки своей инфраструктуры, хорошим вариантом является использование управляемого сервера балансировки нагрузки, такого как ELB (Elastic Load Balancer), поскольку он поддерживает полезные функции, такие как автоматическое масштабирование, и его легко настроить.

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

http {

 upstream myapp1 {
   server srv1.example.com;
   server srv2.example.com;
   server srv3.example.com;
 }
 
 server {
   listen 80;
   location / {
    proxy_pass http://myapp1;
   }
 }
 
}

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

Чтобы распределить трафик между серверами балансировки нагрузки (каждый со своим IP-адресом), вы можете добавить несколько DNS-записей «A» к основному домену, поэтому разрешение DNS будет распределяться между несколькими серверами балансировки нагрузки, которые вы настраиваете. каждый раз на другой IP.

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

Следующий шаг

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

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


Если эта статья была вам полезна, пожалуйста, поставьте мне лайк!

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


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.