Как оптимизировать производственную инфраструктуру Node.js: лучшие практики

Предисловие

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

Наша революция в оптимизации производительности одного ядра на 573%

При переходе с процессоров Intel на AMD Ryzen мы добились повышения производительности наших приложений Node.js на 573%. Это была не просто незначительная оптимизация — она кардинально изменила работу наших приложений Node.js в рабочей среде и продемонстрировала важность оптимизации производительности отдельных ядер для любого приложения Node.js.

Tip

Для передовых методов развертывания Node.js в рабочей среде выбор оборудования имеет решающее значение. Мы выбрали хостинг DataPacket из-за доступности процессоров AMD Ryzen, поскольку производительность одного ядра критически важна для приложений Node.js, поскольку JavaScript выполняется в одном потоке.

Почему оптимизация производительности одного ядра важна для Node.js

Результатом нашего перехода с Intel на AMD Ryzen стали:

  • Повышение производительности на 573% при обработке запросов (документировано в [Проблема GitHub #1519](https://github.com/forwardemail/status.forwardemail.net/issues/1519#issuecomment-2652177671 на нашей странице статуса
  • Устранены задержки обработки, что позволило добиться практически мгновенных ответов (упомянутых в Проблема GitHub #298)
  • Лучшее соотношение цены и производительности для производственных сред Node.js
  • Сокращено время отклика во всех конечных точках наших приложений

Рост производительности оказался настолько значительным, что теперь мы считаем процессоры AMD Ryzen необходимыми для любого серьёзного развертывания Node.js в производственной среде, будь то веб-приложения, API, микросервисы или любые другие рабочие нагрузки Node.js.

Подробнее о наших вариантах инфраструктуры см. здесь:

Настройка производственной среды Node.js: наш технологический стек

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

Менеджер пакетов: pnpm для эффективности производства

Что мы используем: pnpm (закрепленная версия)

Для настройки нашей производственной среды Node.js мы выбрали pnpm вместо npm и yarn по следующим причинам:

  • Более быстрая установка в конвейерах CI/CD
  • Эффективное использование дискового пространства благодаря жёстким ссылкам
  • Строгое разрешение зависимостей, предотвращающее появление фантомных зависимостей
  • Повышенная производительность при развертывании в производственной среде

Note

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

Подробности реализации:

Веб-фреймворк: Koa для современного производства Node.js

Что мы используем:

Мы выбрали Koa вместо Express для нашей производственной инфраструктуры Node.js из-за его современной поддержки async/await и более продуманной структуры промежуточного программного обеспечения. Наш основатель Ник Бо участвовал в разработке как Express, так и Koa, что позволило нам глубоко изучить оба фреймворка для использования в производстве.

Эти шаблоны применимы независимо от того, создаете ли вы REST API, серверы GraphQL, веб-приложения или микросервисы.

Наши примеры реализации:

Обработка фонового задания: Bree для надежности производства

Что мы используем: Планировщик bree

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

Наши примеры реализации:

Обработка ошибок: @hapi/boom для обеспечения надежности производства

Что мы используем: @hapi/boom

Мы используем @hapi/boom для структурированных сообщений об ошибках во всех наших приложениях Node.js. Этот шаблон подходит для любого приложения Node.js, которому требуется согласованная обработка ошибок.

Наши примеры реализации:

Как отслеживать приложения Node.js в процессе производства

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

Мониторинг производства Node.js на системном уровне

Наша основная реализация: helpers/monitor-server.js

Что мы используем: node-os-utils

Наши пороговые значения мониторинга производства (из нашего фактического производственного кода):

  • Ограничение размера кучи 2 ГБ с автоматическими оповещениями
  • Порог предупреждения Использование памяти 25%
  • Порог предупреждения Использование ЦП 80%
  • Порог предупреждения Использование диска 75%

Warning

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

Мониторинг уровня приложения для производства Node.js

Наша классификация ошибок: helpers/is-code-bug.js

Этот помощник различает:

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

Этот шаблон применим к любому приложению Node.js — веб-приложениям, API, микросервисам или фоновым сервисам.

Наша реализация журналирования: helpers/logger.js

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

Мониторинг конкретного приложения

Наши серверные реализации:

Мониторинг очереди: Мы устанавливаем ограничения на размер очереди в 5 ГБ и 180-секундные тайм-ауты для обработки запросов, чтобы предотвратить исчерпание ресурсов. Эти шаблоны применимы к любому приложению Node.js с очередями или фоновой обработкой.

Мониторинг производства Node.js с проверками работоспособности PM2

За годы работы мы усовершенствовали нашу производственную среду Node.js с помощью PM2. Наши проверки работоспособности PM2 необходимы для поддержания надёжности любого приложения Node.js.

Наша система проверки состояния PM2

Наша основная реализация: jobs/check-pm2.js

Наш мониторинг производства Node.js с проверками работоспособности PM2 включает в себя:

  • Запускается каждые 20 минут с помощью cron-планировщика
  • Требуется минимум 15 минут бесперебойной работы, прежде чем процесс будет признан работоспособным
  • Проверяет состояние процесса и использование памяти
  • Автоматически перезапускает сбойные процессы
  • Предотвращает циклические перезапуски благодаря интеллектуальной проверке работоспособности

Caution

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

Наша производственная конфигурация PM2

Настройка нашей экосистемы: Изучите файлы запуска нашего сервера для настройки производственной среды Node.js:

Эти шаблоны применимы независимо от того, используете ли вы приложения Express, серверы Koa, API GraphQL или любые другие приложения Node.js.

Автоматизированное развертывание PM2

Развертывание PM2: ansible/playbooks/node.yml

Мы автоматизируем всю настройку PM2 с помощью Ansible, чтобы гарантировать единообразное развертывание Node.js на всех наших серверах.

Система обработки и классификации производственных ошибок

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

Наша реализация isCodeBug для производства

Источник: helpers/is-code-bug.js

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

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

Этот шаблон работает для любого приложения Node.js — создаете ли вы сайты электронной коммерции, платформы SaaS, API или микросервисы.

Интеграция с нашим производственным журналом

Наша интеграция с регистратором: helpers/logger.js

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

Узнайте больше о наших шаблонах обработки ошибок:

Расширенная отладка производительности с помощью v8-profiler-next и cpupro

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

Наш подход к профилированию для производства Node.js

Инструменты, которые мы рекомендуем:

  • v8-profiler-next — для создания снимков кучи и профилей ЦП
  • cpupro — для анализа профилей ЦП и снимков кучи

Tip

Мы используем v8-profiler-next и cpupro вместе для создания полноценного рабочего процесса отладки производительности наших приложений Node.js. Это сочетание помогает нам выявлять утечки памяти, узкие места производительности и оптимизировать наш рабочий код.

Как мы реализуем анализ моментальных снимков кучи

Наша реализация мониторинга: helpers/monitor-server.js

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

Ключевые шаблоны реализации:

  • Автоматическое создание снимков при превышении размера кучи порогового значения в 2 ГБ
  • Профилирование на основе сигналов для анализа по запросу в производственной среде
  • Политики хранения для управления хранилищем снимков
  • Интеграция с нашими заданиями очистки для автоматизированного обслуживания

Рабочий процесс отладки производительности

Изучите нашу фактическую реализацию:

Для анализа моментального снимка кучи:

  1. Установите v8-profiler-next для создания снимков
  2. Используйте cpupro для анализа созданных снимков
  3. Реализуйте пороговые значения мониторинга, аналогичные нашему monitor-server.js
  4. Настройте автоматическую очистку для управления хранилищем снимков
  5. Создайте обработчики сигналов для профилирования по требованию в рабочей среде

Для профилирования ЦП:

  1. Создание профилей ЦП в периоды высокой нагрузки
  2. Анализ с помощью cpupro для выявления узких мест
  3. Сосредоточение на горячих путях и возможностях оптимизации
  4. Отслеживание улучшений производительности до и после

Warning

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

Интеграция с нашим производственным мониторингом

Наши инструменты профилирования интегрируются с нашей более широкой стратегией мониторинга:

  • Автоматическое срабатывание на основе пороговых значений памяти/процессора
  • Интеграция оповещений при обнаружении проблем с производительностью
  • Исторический анализ для отслеживания тенденций производительности с течением времени
  • Корреляция с метриками приложения для комплексной отладки

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

Безопасность производственной инфраструктуры Node.js

Мы обеспечиваем комплексную безопасность нашей производственной инфраструктуры Node.js с помощью автоматизации Ansible. Эти методы применимы к любому приложению Node.js:

Безопасность на системном уровне для производства Node.js

Наша реализация Ansible: ansible/playbooks/security.yml

Наши основные меры безопасности для производственных сред Node.js:

  • Подкачка отключена для предотвращения записи конфиденциальных данных на диск
  • Дампы ядра отключены для предотвращения записи дампов памяти, содержащих конфиденциальную информацию
  • USB-накопитель заблокирован для предотвращения несанкционированного доступа к данным
  • Настройка параметров ядра для обеспечения безопасности и производительности

Warning

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

Безопасность приложений Node.js

Наше редактирование поля журнала: helpers/logger.js

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

Автоматизация безопасности инфраструктуры

Наша полная настройка Ansible для производства Node.js:

Наш контент безопасности

Узнайте больше о нашем подходе к обеспечению безопасности:

Архитектура базы данных для приложений Node.js

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

Реализация SQLite для производства Node.js

Что мы используем:

Наша конфигурация: ansible/playbooks/sqlite.yml

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

  • Изоляция данных для каждого пользователя/клиента
  • Повышенная производительность для однопользовательских запросов
  • Упрощенное резервное копирование и миграция
  • Снижение сложности по сравнению с общими базами данных

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

Реализация MongoDB для производства Node.js

Что мы используем:

Наша реализация настройки: helpers/setup-mongoose.js

Наша конфигурация: config/mongoose.js

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

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

Note

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

Обработка фоновых заданий Node.js

Мы построили архитектуру фоновых заданий на основе Bree для надёжного развертывания Node.js в продакшене. Это применимо к любому приложению Node.js, требующему фоновой обработки:

Наша настройка сервера Bree для производства

Наша основная реализация: bree.js

Наше развертывание Ansible: ansible/playbooks/bree.yml

Примеры производственных заданий

Мониторинг здоровья: jobs/check-pm2.js

Автоматизация очистки: jobs/cleanup-tmp.js

Все наши вакансии: Просмотрите наш полный каталог вакансий

Эти шаблоны применимы к любому приложению Node.js, которому требуется:

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

Наши шаблоны планирования заданий для производства Node.js

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

  • Как мы реализуем cron-подобное планирование в продакшене Node.js
  • Наша обработка ошибок и логика повторных попыток
  • Как мы используем рабочие потоки для задач, интенсивно использующих процессор

Автоматизированное обслуживание производственных приложений Node.js

Мы внедряем проактивное обслуживание для предотвращения распространённых проблем в работе Node.js. Эти шаблоны применимы к любому приложению Node.js:

Наша реализация очистки

Источник: jobs/cleanup-tmp.js

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

  • Временные файлы старше 24 часов
  • Файлы журналов, срок хранения которых истек
  • Файлы кэша и временные данные
  • Загруженные файлы, которые больше не нужны
  • Снимки кучи, полученные при отладке производительности

Эти шаблоны применимы к любому приложению Node.js, которое генерирует временные файлы, журналы или кэшированные данные.

Управление дисковым пространством для производства Node.js

Наши пороговые значения мониторинга: helpers/monitor-server.js

  • Ограничения очереди для фоновой обработки
  • **Порог предупреждения о использовании диска 75%
  • Автоматическая очистка при превышении пороговых значений

Автоматизация обслуживания инфраструктуры

Наша автоматизация Ansible для производства Node.js:

Руководство по внедрению производственного развертывания Node.js

Изучите наш реальный код для лучших практик производства

Начните с этих ключевых файлов для настройки производственной среды Node.js:

  1. Конфигурация: config/index.js
  2. Мониторинг: helpers/monitor-server.js
  3. Обработка ошибок: helpers/is-code-bug.js
  4. Ведение журнала: helpers/logger.js
  5. Состояние процесса: jobs/check-pm2.js

Узнайте из наших постов в блоге

Наши технические руководства по внедрению для производства Node.js:

Автоматизация инфраструктуры для производства Node.js

Наши руководства по Ansible для изучения при развертывании Node.js в продакшене:

Наши примеры

Наши корпоративные внедрения:

Заключение: лучшие практики развертывания Node.js в продакшене

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

  • Проверенный выбор оборудования (AMD Ryzen для оптимизации производительности одного ядра на 573%)
  • Проверенный в реальных условиях мониторинг производительности Node.js с заданными пороговыми значениями и автоматизированными ответами
  • Интеллектуальная классификация ошибок для улучшения реагирования на инциденты в производственной среде
  • Расширенная отладка производительности с v8-profiler-next и cpupro для предотвращения OOM
  • Комплексное усиление безопасности благодаря автоматизации Ansible
  • Гибридная архитектура базы данных, оптимизированная для потребностей приложений
  • Автоматизированное обслуживание для предотвращения распространенных проблем в производственной среде Node.js

Ключевой вывод: Изучайте наши файлы реализации и записи в блоге, а не следуйте общим рекомендациям. Наша кодовая база предоставляет реальные шаблоны для развертывания Node.js в рабочей среде, которые можно адаптировать для любого приложения Node.js — веб-приложений, API, микросервисов или фоновых служб.

Полный список ресурсов для производства Node.js

Наши основные файлы реализации

Наши серверные реализации

Наша автоматизация инфраструктуры

Наши технические записи в блоге

Наши примеры использования на предприятии