Як оптимізувати продакшн-інфраструктуру Node.js: найкращі практики

Node.js performance optimization guide

Передмова

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

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

Коли ми перейшли з процесорів Intel на AMD Ryzen, ми досягли 573% покращення продуктивності у наших Node.js додатках. Це була не просто незначна оптимізація — це фундаментально змінило те, як наші Node.js додатки працюють у виробництві, і демонструє важливість оптимізації продуктивності одного ядра для будь-якого Node.js додатку.

Tip

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

Чому оптимізація продуктивності одного ядра важлива для Node.js

Наш перехід з Intel на AMD Ryzen призвів до:

  • 573% покращення продуктивності у обробці запитів (задокументовано у GitHub Issue #1519 на нашій сторінці статусу)
  • Усунення затримок обробки до майже миттєвих відповідей (згадується у GitHub Issue #298)
  • Кращого співвідношення ціна-продуктивність для виробничих середовищ Node.js
  • Покращення часу відгуку на всіх кінцевих точках нашого додатку

Покращення продуктивності було настільки значним, що ми тепер вважаємо процесори AMD Ryzen необхідними для будь-якого серйозного розгортання Node.js у виробництві, незалежно від того, чи запускаєте ви веб-додатки, API, мікросервіси чи будь-яке інше навантаження Node.js.

Для детальнішої інформації про наш вибір інфраструктури перегляньте:

Налаштування виробничого середовища Node.js: наш технологічний стек

Наші найкращі практики розгортання Node.js у виробництві включають свідомий вибір технологій на основі багаторічного досвіду у виробництві. Ось що ми використовуємо і чому ці вибори застосовні до будь-якого Node.js додатку:

Менеджер пакетів: pnpm для ефективності у виробництві

Що ми використовуємо: pnpm (фіксована версія)

Ми обрали pnpm замість npm та yarn для налаштування нашого виробничого середовища Node.js через:

  • Швидший час встановлення у CI/CD конвеєрах
  • Ефективність використання дискового простору завдяки жорстким посиланням
  • Строге розв’язання залежностей, що запобігає фантомним залежностям
  • Кращу продуктивність у виробничих розгортаннях

Note

Як частина наших найкращих практик розгортання Node.js у виробництві, ми фіксуємо точні версії критичних інструментів, таких як pnpm, щоб забезпечити послідовну поведінку у всіх середовищах та на машинах членів команди.

Деталі впровадження:

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

Що ми використовуємо:

  • @koa/router
  • @koa/multer
  • @ladjs/koa-simple-ratelimit Ми обрали Koa замість Express для нашої продакшн-інфраструктури на Node.js через його сучасну підтримку async/await та чистішу композицію middleware. Наш засновник Нік Бауґ зробив внесок у обидва фреймворки — 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

Наші пороги моніторингу в продакшн (з нашого реального продакшн-коду):

  • Ліміт heap 2GB з автоматичними сповіщеннями
  • Попередження при використанні пам’яті 25%
  • Сповіщення при використанні CPU 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 Health Checks

Ми вдосконалили налаштування нашого продакшн-середовища Node.js з PM2 за роки досвіду у продакшні. Наші перевірки стану PM2 є необхідними для підтримки надійності будь-якого Node.js застосунку.

Наша система перевірки стану PM2

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

Наш моніторинг продакшн Node.js з PM2 health checks включає:

  • Виконується кожні 20 хвилин за розкладом cron
  • Вимагає мінімум 15 хвилин безперервної роботи перед визнанням процесу здоровим
  • Перевіряє статус процесу та використання пам’яті
  • Автоматично перезапускає збої процесів
  • Запобігає циклам перезапуску завдяки інтелектуальній перевірці стану

Caution

Для найкращих практик розгортання Node.js у продакшн ми вимагаємо 15+ хвилин безперервної роботи перед визнанням процесу здоровим, щоб уникнути циклів перезапуску. Це запобігає каскадним збоям, коли процеси мають проблеми з пам’яттю або іншими питаннями.

Наша продакшн-конфігурація PM2

Налаштування нашої екосистеми: Вивчіть наші файли запуску серверів для налаштування продакшн-середовища Node.js:

Ці патерни застосовні, чи ви запускаєте Express додатки, Koa сервери, GraphQL API або будь-який інший 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 (Out of Memory), вузьких місць продуктивності та проблем пам’яті Node.js у нашому продакшн-середовищі. Ці інструменти є необхідними для будь-якого Node.js-додатку, що стикається з витоками пам’яті або проблемами продуктивності.

Наш підхід до профілювання для продакшн Node.js

Інструменти, які ми рекомендуємо:

  • v8-profiler-next - Для створення знімків купи та профілів CPU
  • cpupro - Для аналізу профілів CPU та знімків купи

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. Створіть обробники сигналів для профілювання за запитом у продакшн

Для профілювання CPU:

  1. Створюйте профілі CPU під час періодів високого навантаження
  2. Аналізуйте за допомогою cpupro для виявлення вузьких місць
  3. Зосередьтеся на гарячих шляхах та можливостях оптимізації
  4. Моніторте до/після покращень продуктивності

Warning

Створення знімків купи та профілів CPU може впливати на продуктивність. Ми рекомендуємо реалізувати обмеження частоти та вмикати профілювання лише під час розслідування конкретних проблем або в періоди обслуговування.

Інтеграція з нашим продакшн-моніторингом

Наші інструменти профілювання інтегруються з нашою ширшою стратегією моніторингу:

  • Автоматичне спрацьовування на основі порогів пам’яті/CPU
  • Інтеграція оповіщень при виявленні проблем продуктивності
  • Історичний аналіз для відстеження тенденцій продуктивності з часом
  • Кореляція з метриками додатку для комплексного налагодження Цей підхід допоміг нам виявити та усунути витоки пам’яті, оптимізувати гарячі ділянки коду та підтримувати стабільну продуктивність у нашому виробничому середовищі Node.js.

Безпека виробничої інфраструктури Node.js

Ми впроваджуємо комплексну безпеку для нашої виробничої інфраструктури Node.js за допомогою автоматизації Ansible. Ці практики застосовуються до будь-якого додатку Node.js:

Безпека на рівні системи для виробництва Node.js

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

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

  • Контрольоване використання swap зберігає хости застосунків та інші хости, що не є базами даних, без swap, а їх розмір налаштований так, щоб звичайні робочі навантаження залишалися в RAM, тоді як хости MongoDB та Redis використовують файл swap лише для root з vm.swappiness=1 суворо як захисну сітку від нестачі пам'яті; активність swap бази даних відстежується та розслідується
  • Відключені core dumps для запобігання дампам пам’яті, що містять конфіденційну інформацію
  • Заблоковане USB-зберігання для запобігання несанкціонованому доступу до даних
  • Налаштування параметрів ядра для безпеки та продуктивності

Note

Використання swap у продакшені є захисною сіткою від нестачі пам'яті, а не звичайною ємністю. Хости застосунків залишаються без swap, і очікується, що звичайні робочі навантаження залишатимуться в RAM.

Безпека додатків для 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

Що ми використовуємо:

Наша конфігурація: 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 години
  • Файли журналів поза межами термінів зберігання
  • Файли кешу та тимчасові дані
  • Завантажені файли, які більше не потрібні
  • Знімки купи (heap snapshots) для налагодження продуктивності

Ці шаблони застосовуються до будь-якого додатку 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 playbooks для вивчення розгортання 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

Наші Основні Файли Впровадження

Наші серверні реалізації

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

Наші технічні публікації в блозі

Наші корпоративні кейс-стаді