Комментарии 53
habrahabr.ru/post/268583/#comment_8608261
Мы это делаем путем внесения правок в конфиг и релоада nginx до и после перезагрузки инстанса.
а почему не через pm2 graceful reload? кстати говоря, у них есть ещё keymetrics.io, из которой можно делать ручной graceful reload и прочие полезные штуки
Теперь перед этими 4-ма инстанами нужно установить балансировщик, который будет распределять нагрузку
Тут, есть множество вариантов, например: Запустить еще один инстанс ноды и задействовать модуль cluster
Cluster-модуль содержит балансировку по воркерам внутри себя, ничего дополнительно ставить не нужно. А вот для статики — действительно, неплохо иметь nginx сверху. Но это опять же ничуть не исключает наличия кластер-модуля в апстриме.
Периодичность перезагрузки (в зависимости от разных причин) от 1 раза в час до 1 раза в сутки.
Я могу понять когда сервис жрет память и не отдает (от чего кстати хорошо помогают лимиты по использованию памяти в pm2), но от чего сервис может становиться более медленным с течением времени — непонятно. Так или иначе, выше уже упомянули про graceful reload. И да, перезагружать весь инстанс довольно странно, если есть кластер-модуль и можно, грубо говоря, послать SIGTERM медленному воркеру.
написано множество cli утилит, которые следят за процессом ноды и в случае необходимости его перегружают
Не могу сказать за остальные три, но могу сказать за pm2 — падает как миленький весь God Daemon :) Особенно на node/io от 0.11 до 4.1.2, из-за бага, имевшего место быть в тех версиях в модуле кластера. Так что за pm2 тоже желательно следить, через upstart-скрипт, например. А можно вообще впилить голый кластер-модуль и мониторить/перезагружать его опять же через upstart.
По пункту 10 — чот вообще вcё в кучу смешалось. Да, мониторинг нужен. Да, юнит-тестирование нужно. Но из пункта сложилось впечатление, что вы предлагаете использовать mocha/jasmine на продакшене для проверки окружения о.0 Это довольно странный способ использования этих фреймворков.
Не могу сказать за остальные три, но могу сказать за pm2 — падает как миленький весь God Daemon :) Особенно на node/io от 0.11 до 4.1.2, из-за бага, имевшего место быть в тех версиях в модуле кластера.
Вы говорите о встроенной кластеризации pm2? У меня сейчас на проекте запускаются воркеры через apps.json с записанными апстримами в nginx, ни одного вылета не заметил
И я кажется наврал насчет версии, вроде в io v3 фикс уже приземлился :)
Я могу понять когда сервис жрет память и не отдает (от чего кстати хорошо помогают лимиты по использованию памяти в pm2), но от чего сервис может становиться более медленным с течением времени — непонятно. Так или иначе, выше уже упомянули про graceful reload.
Если даже код идеален, сервис теряет приоритет для операционной системы и начинает работать медленее и это есть проблема. В nginx, например, можно задать принудительно приоритет для процесса параметром worker_priority.
И да, перезагружать весь инстанс довольно странно, если есть кластер-модуль и можно, грубо говоря, послать SIGTERM медленному воркеру.
Вы невнимательно читали, можно использовать модуль cluster, и я об этом написал. Это менее стабильное решение чем балансировщик nginx или ha-proxy. Я не могу понять чем так плохо раз в сутки ребутнуть инстанс ноды?
По пункту 10 — чот вообще вcё в кучу смешалось. Да, мониторинг нужен. Да, юнит-тестирование нужно. Но из пункта сложилось впечатление, что вы предлагаете использовать mocha/jasmine на продакшене для проверки окружения о.0 Это довольно странный способ использования этих фреймворков.
Не совсем так, я не нашел время чтоб расписать, это будет в следующих сериях. В каждом проекте, есть папочка ./spec, там лежат тесты, и да перед тем как на продакшине запустить приложение после апдейта именно на продакшине надо запустить npm test и убедиться что все работает.
Я не могу понять чем так плохо раз в сутки ребутнуть инстанс ноды?Зависит от нагрузки :) Ребут инстанса означает, что некоторые клиенты могут отвалиться от сервиса или не смогут достучаться до него. Если ночью инстанс пустует — почему бы и нет.
именно на продакшине надо запустить npm test и убедиться что все работаетВы не думали о внедрении continuous integration с прогоном всех тестов на тестовых средах, идентичных боевым?
Уходите от REST-а, вы его переросли. Переходите на AMQP (а именно RabbitMQ с роутингом). Это даст вам асинхронность и все преимущества event-based loose-coupling системы. В том числе такие приятные вещи, как параллелизация нагруженных узлов, кворумные воутеры, возможность рестарта любого сервиса без потерь, dry-run новых версий сервисов, debug «на ходу» и т.д.
А во вторых — очень любопытно, как вы решаете вопросы совместимости API при внесении breaking changes? Когда у вас десятки сервисов, предполагаю, вам нужно или передепловать всю кучу на новую версию API или поддерживать две версии одновременно. Как именно вы поступаете?
Нода под нагрузкой требует увеличения ограничения nofile limit
Зачем он вам? Вы же не отдаете статику через ноду?
Инстанс под нагрузкой, который работает продолжительное время начинает «тормозить»
Можете примерно сказать нагрузку? У нас тоже есть такое, но начинают тормозить инстансы с говнокодом. За нормальными такого замечено не было.
9. Не бойтесь использовать ECMAScript 2015 (ES6)
Извините, но пример совершенно не впечатляет, т.к. можно использовать
arr1 = arr1.concat(arr2);
без всяких ES6
Может кто-нибудь посоветовать пример проекта с грамотно построенной микросервисной архитектурой?
Хотя там ориентация была в сторону контейнеризации и использования tutum сервиса для CI
У меня ещё есть сайт написанный на node.js, там тоже всё отлажено, писал давно его и долго мучился сначала, но после того, как все проблемы устранил — работает без перезагрузок вообще, поскольку код там не обновляется, аптайм там месяцами измеряется. Ну и все относительно популярные модули npm довольно серьёзно относятся к проблемам утечек памяти, в целом с ними там ситуация хорошая, их либо нет, либо их быстро исправляют.
В общем, присоединюсь к просьбе поделиться опытом, возможно даже в виде статьи, а не комментария :)
Да тут указан лимит «с запасом», а в чем проблема увеличения этого лимита?
В следующих сериях мы рассмотрим тюнинг ядра для нужд ноды, грабли виртуализации, как правильно закэшировать nginx-ом ответы от инстансов nodejs.
"..., а Германа всё нет."
Нода не однопоточная, так как использует под капотом libuv, который как минимум использует дополнительный поток для i/o операций да и несколько потоков для работы с запросами ей ни к чему, там все работает на основе non-blocking event-driven I/O. W. Richard Stevens в своей книге "Unix network programming" отлично объясняет этот момент
Node.js является однопоточным по своей сути. Он работает в одном потоке через архитектуру Event Loop. Да он использует библиотеку libuv в отдельном потоке, но многопоточный код все равно написать не получиться, если это не так то напишите мне пример кода который работает, к примеру, в 10 потоков.
В контексте этой статьи если у вас 4 ядра, напишите мне код на nodejs, который займет ресурсы всех 4-х ядер, кроме варианта запустить одновременно 4 копии одного и того же js-скрипта.
worker_threads, нативная библиотека ноды, создает реальный отдельный поток
Это неполноценная многопоточность, по сути библиотека запускает отдельный инстанс nodejs для каждого потока и организовывает общение между потоками через специальные объекты message passing, при этом у потоков нету доступа к общим ресурсам, нету общих переменных, общего контекста, невозможно организовать прослушивание веб-сервером одного и того же порта, там можно поизвращаться и передавать дочерним потокам запросы, но это уже будут "костыли".
Поэтому все пункты статьи остаются актуальными, надежнее запустить reverse proxy (например, nginx) и за ним несколько отдельных инстансов nodejs, чем колхозить на worker_threads.
Да, нужно отталкиваться от особенностей исполнения JS. Нода не может сделатть, как это делается в том же питоне. Но тем не менее все равно есть один процесс ноды, в нем несколько потоков исполняют JS. Если надо шарить память, то можно использовать SharedArrayBuffer, который не использует какие-то техники IPC, а вот именно что в рамках одного процесса шарит буферы
Повышаем отказоустойчивость системы на nodejs