Pull to refresh

Comments 26

Гляньте http://pm2.keymetrics.io/ и https://github.com/Unitech/pm2, там и поддержка systemd, и GUI, и CLI, и API, и hotreload, балансировка, защита от падений, управление кучей серверов одной командой (в том числе деплой на них, в конфиге на машине деплоящего разработчика достаточно указать только SSH-доступы подконтрольных серверов, все нужные пакеты для разворачивания pm2 он поставит сам). В общем, полное и универсальное решение (воркерами не обязаны быть исключительно скрипты для node.js, можно запускать любые программы), построенное на базе npm-инфраструктуры.
Спасибо, обязательно посмотрю. Однако свой велосипед не просто так появился. Он эволюционировал из множества реализованных проектов и тесно связан с разрабатываемыми проектами.
У вас получился некий «сервер приложений-демонов», под который нужно отдельно писать апплеты, отдельно реализовывать стратегии деплоя и обновления кода апплетов, а pm2 сразу предлагает универсальное решение, под управление которого можно будет отдать разрабатываемые сервисы вне зависимости от их происхождения и языка написания, и покрывающее сразу большой кусок задач в цикле разработки/эксплуатации ПО (DevOps). Такой единый инструмент для управления всем ландшафтом. Я ни в коем случае не говорю «зря делали», наоборот, говорю о том, что может получиться в итоге. Альтернативы всегда полезны.
Пробовали у себя. Поплевались, выбросили. pm2 при работе в режиме кластера напрочь забивает сетевой стек висящими соединениями. Как итог — серьезное увеличение числа 50х ответов. У nodejs и так-то кластерный модуль через пень-колоду написан, а pm2 еще и своих глюков добавляет. Рекомендовать его для хоть сколько-нибудь серьезных проектов не могу.
И кстати, в исходный код pm2 лучше не смотреть людям с неустойчивой психикой.
Проект развивается, возможно, вы плевались слишком давно. Сам с серьезными проблемами не сталкивался.
Впрочем, ваш бойлерплейт скорее не про демонизацию, а про очередь задач и пул воркеров (а демонизировать можно и с помощью pm2, отдав ему работу по деплою, горячей перезагрузке и мониторингу нагрузки). Потому таки не очевидно, почему вы не выбрали архитектуру с шиной типа MQ, т.к. вместо активной мастер-ноды, раздающей задачи, вы сделали пассивную мастер-ноду с БД, у которой воркеры будут сами запрашивать задачи. Т.е., точка отказа таким решением не устраняется всё равно, а воркеры получаются неабстрагированными от хранилища задач. (Но это может быть, конечно, удобным в вашем проекте.)
Впрочем, ваш бойлерплейт скорее не про демонизацию, а про очередь задач и воркеров (а демонизировать можно и с помощью pm2, отдав ему работу по деплою, горячей перезагрузке и мониторингу нагрузки).

Вы правы, демонизация это только часть бойлерплейта. Упор сделан на обработке задач. Нужно подумать над интеграцией pm2 в проект.

Потому таки неясно, почему вы не выбрали архитектуру с шиной типа MQ

Одно из исходных условий — мониторинг и управление задачами из самого приложения (куда интегрируется этот проект). Соответственно хранение задач в базе данных — лучший, если не единственный, выбор. Конечно можно сделать гибридное решение, когда задачи находятся в базе данных, а нотификация о поступлении задач проходит через MQ. Но в этом случае появляется еще одна зависимость и все приходится дополнительно налаживать синхронизацию задач между базой и MQ.

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

На данном уровне отказоустойчивость базы данных принципиально не рассматривается. Если база упала, то падает и весь проект. Отказоустойчивость базы данных настраивается отдельно.
Запрашиваемая конструктивная критика:

  1. Задачи должны находиться в таблице MySQL. Это намного гибче и информативнее, чем использовать какой-нибудь MQ.

    Создается впечатление, что в вашей команде просто не хватает экспертизы по работе с очередями.
  2. Не ясно почему написан boirplate, а не генератор
  3. Зачем использовать bluebird, когда в требованиях packege.json 4-ая нода с нативными промисами?
  4. Странный код стайл. Подключите eslint
  5. Если вы выкладываете в opensourse то следите за актуальность readme.md Это важнее чем статья на хабре.
  6. В некоторых местах кода вызывает недоверие

  7. Тестов нет. Travis и TDD


И на последок главный вопрос, а что вы анализировали из готовых решений в opensource?
Спасибо за критику.

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

> Не ясно почему написан boirplate, а не генератор
Генераторы не используем. Не думаю что это минус.

> Зачем использовать bluebird, когда в требованиях packege.json 4-ая нода с нативными промисами?

Еще начали использовать обертки над промисами с версии 0.10.x. Ипользовали Q, перешли к bluebird. У blurbid есть много «плюшек», таких как promisifyAll, delay и т.д. Здесь они пока не используются, но могут быть использованы в будущем.

> Странный код стайл. Подключите eslint
Что вас смутило в код стайле? eslint подключу обязательно.

> Если вы выкладываете в opensourse то следите за актуальность readme.md Это важнее чем статья на хабре.
До README.md еще не добрался. Сначала решил выложить статью на хабре.

> изменяем переменную из окружения?
Пример взят из документации log4js https://github.com/nomiddlename/log4js-node#configuration
Можно конечно использовать метод configure, согласен. Нужно изменить.

> куча then и не одного catch?
Все верно, результат метода обрабатывается в базовом воркере. Это описано в статье.

> Тестов нет. Travis и TDD
Про тесты я так же в статье писал, что это в планах.

> И на последок главный вопрос, а что вы анализировали из готовых решений в opensource?
Как я уже писал выше, реализация эволюционировала из проектов, над которыми мы работали вот уже более 5-ти лет. Соответственно сформировались свои требования и были отработаны многие моменты. Так что изыскания я не проводил.
(Вне контекста самой статьи и остальных замечаний).
Зачем использовать bluebird, когда в требованиях packege.json 4-ая нода с нативными промисами?


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

Плюс текущий API Node.js сам по себе промисы пока ещё не возвращает, а bluebird даёт promisifyAll.
А где можно по-подробней об этом прочитать? Мы не сталкивались с такими проблемами.

https://github.com/petkaantonov/bluebird/tree/master/benchmark посмотрите, например.
Ну и https://github.com/nodejs/node/issues/3414.


Плюс в стандарте кое-чего не совсем гладко, а bluebird от него в этом месте отходит, и за счёт этого несколько выигрывает.
См. https://github.com/promises-aplus/promises-spec/issues/179 и https://github.com/promises-aplus/promises-spec/issues/183.

С другой стороны, переопределять глобальный Promise я бы не стал.
Я просто делаю const Promise = require('bluebird'); наверху каждого файла.

Выше уже посоветовали pm2 для демонизации. Дополнительно хочу посоветовать посмотреть в сторону Seneca для построения распределенных воркеров.
Спасибо, про Seneca впервые слышу. Обязательно посмотрю.
А чем модуль cluster лучше pm2 (http://pm2.keymetrics.io/)?
Как минимум cluster это встроенный модуль, а pm2 — сторонний.
И что? Если сторонний механизм лучше встроенного, почему бы не использовать его?
Если честно, я модуль pm2 даже не рассматривал. Для форка процессов я использовал cluster из-за простого API.
pm2 использует cluster-модуль внутри себя, поэтому «кто лучше» — вопрос неправильный. Помимо (коряво реализованных) управления процессами и балансировки запросов по процессам у pm2 есть масса других привлекательных плюшек, которые зачастую определяют выбор.
А можно подробнее про корявость и плюшки? Мы сейчас используем pm2, поэтому и интересны все +\-.
Плюшки все указаны в readme, в их числе — авто-перезапуск при падении, софт-рестарт воркера при превышении лимитов по памяти или процессору, поддержка деплоя через репозиторий и прочее. При прочих равных — довольно вкусные возможности.

Насчет корявостей — в cluster-модуле балансировка пакетов по воркерам может работать нестабильно. Не скажу за последние версии ноды, инфа актуальна на версии 0.12 — 4.2. До версии node 4.0 кстати кластер-модуль вообще не работал под нагрузкой — мастер-процесс, а также и god daemon (в случае пм2) просто падал напрочь через 5 минут вместе со всеми воркерами. Потом починили, вроде, но с pm2 (опять же под нагрузкой) началось жесткое забивание сетевого стека висящими коннектами. Предположительно из-за того, что при софтовом перезапуске воркера сокет для общения с god daemon-ом оставался висеть, но я в код настолько глубоко не залезал и не проверял, точно говорить не могу. Симптомы — частые неответы сервера и 50х ошибки. После замены pm2 и кластерного режима nodejs на балансировку nginx-ом по вручную созданным воркерам — исчезли почти все проблемы и общая стабильность значительно повысилась.
в их числе — авто-перезапуск при падении,


Пусть в меня снова кинут тапком (как в прошлый раз), но нет.

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

Если вы разворачиваете что-то на pm2 — вам нужно убедиться, что сам pm2 перезапустится при его падении, точно так же, как в случае без pm2 вам надо было убедиться, что ваша программа перезапустится. pm2 этой задачи не решает.
Да, справедливо. Имел в виду перезапуск воркера, но это же можно сделать тремя строчками и используя голый кластерный модуль :) Промашка вышла.
Насчёт плюшёк — не то, что написано в readme, а то, чем он лучше cluster'a. Мы используем ноду (6.1/6.2) и перезапуск через pm2. Обслуживаем в среднем 200-250 rps. Таких симптомов, как вы описали не замечал.
Отвечу то, же что и парой комментов выше — он не лучше кластера ничем, кроме наворотов сверху, потому что внутри себя pm2 непосредственно использует cluster.
Sign up to leave a comment.

Articles