Время от времени у разработчиков, поддерживающих старые нодовые приложения, возникают сомнения в необходимости переноса приложения со старых версий ноды на новые.
Главный аргумент в пользу сохранения старых — «Новыми фичами я не пользуюсь, но их реализация, вероятно, замедляет обработку в целом».
Плюс ситуацию может сильно усложнить наличие зависимостей от библиотек, которые больше не поддерживаются под новыми узлами, а смена версии узла автоматически приводит к существенной переработке архитектуры приложения.
Моя статья, надеюсь, поможет им определиться в этом вопросе.
Прежде чем мы начнем, позвольте мне напомнить вам основной принцип ИТ-бизнеса: РАБОТАЕТ, НЕ ТРОГАЙТЕ! Если ваше приложение работает как надо, если оно полностью справляется со своими задачами и нет острой необходимости его переделки, лучше оставить все как есть.
Переработка может быть очень болезненным и длительным процессом.
И в результате вы не получите никакой реальной ощутимой выгоды, кроме чувства эстетического удовлетворения, а ваш бизнес тем временем пострадает. Моя статья для тех, у кого еще есть потребность.
Я опишу свою недавнюю ситуацию, расскажу о трудностях, с которыми столкнулся при ее разрешении, и представлю результаты, которые я в итоге получил.
Разрабатываю систему сбора и обработки логов других приложений.
Стандартные рабочие нагрузки — это сотни тысяч журналов в минуту на каждый компонент. Система хорошо масштабировалась по горизонтали, имела модульную архитектуру, успешно работала много лет и в целом справлялась со своими функциями.
Используемая версия узла была 0.10. С чем вы столкнулись? Естественно, не недостаток функциональности.
Новые возможности es6 даже не рассматривались как аргумент. Конечно, они делают жизнь немного приятнее, но не более того.
Для любой нашей задачи функционала старого узла вполне хватало.
Проблемы возникали в самых неожиданных местах по мере усложнения функционала.
Проблема первая: Один из компонентов при пиковых входящих нагрузках и потреблении памяти до 5Гб вдруг начал чертовски тормозить.
Проблема возникала не каждый раз, спонтанно, обычно ближе к концу пика.
Если приложение не падало из-за таймаутов, работоспособность постепенно восстанавливалась в течение получаса-часа.
Перезагрузка вылечила сразу.
После процесса «глубокой отладки» выяснилось, что весь процесс стал тормозить, даже синхронные операции, из-за чего пришли к выводу, что сборщик мусора самой ноды «плохой».
Что с этим делать, было совершенно непонятно.
Единственным решением было просмотреть историю изменений нашего кода за несколько месяцев и откатить важный функционал.
С другой стороны, проблема возникала не часто, не каждый день, и перезагрузка системы вручную тоже казалась вполне приемлемым решением (ручной подразумевает использование скрипта, основанного на сигнале детектора лагов).
Мы больше склонялись ко второму варианту.
И если бы не вторая проблема, то, скорее всего, она была бы реализована.
Проблема вторая: Еще один наш компонент съедал заметное количество памяти.
Поскольку этот компонент по сути был кэшем, его «жадность» была в принципе понятна.
До того момента, пока не пришлось ограничить его сверху строго заданным объемом.
А потом оказалось, что компонент набирает память и не спешит от нее отказываться.
Причём даже работая практически на холостом ходу.
То есть в момент пиковой нагрузки менеджер памяти узла выбирал максимальную память, да еще с запасом, и после этого сохранял ее до конца времени (например, перезагрузки компонента).
Сразу отмечу, что естественно вариант с утечкой был рассмотрен и проверен.
Увы, утечек не произошло, и мы снова оказались в тупике.
Я пробовал в разных местах Интернета спрашивать, как отладить управление памятью узла и как разрешить нашу ситуацию.
Но в ответ получил только массу негатива по поводу использования ноды 0.10. В общем, именно этот негатив побудил меня взяться за задачу перехода на последние версии ноды.
Что тебя сдерживало? 1. Страхи потери продуктивности.
Любой, кто работал на Python, помнит, что переход с линейки 2.x на 3.x сопровождался значительной потерей производительности.
Не знаю, как сейчас обстоят дела в Python, возможно, ситуация улучшилась.
Но вполне логично ожидать, что после добавления всех этих новых возможностей es6 нода также может существенно пострадать.
Я пытался поискать в Google бенчмарки для сравнения новых узлов со старыми, но не нашел ничего полезного.
2. Производительность JSON.parse Поскольку мы работаем с логами, JSON.parse занимает львиную долю процессора.
В свое время мы сравнили его на разных версиях узла и получили падение производительности примерно на 30%.
Node 4.x сравнивался с версиями 0,10 и 0,12. На самом деле эти причины не были решающими, поскольку процессор не был узким местом.
Кроме того, для таких задач существует горизонтальное масштабирование.
3. Зависимости пакетов Но это было камнем преткновения.
Наш центральный самый сложный компонент использовал пакет libmysqlclient, который работает только под узлом 0.10. Еще хуже его синхронные вызовы.
То есть невозможно было просто изменить драйвер mysql, заменив одни вызовы другими, без глубокой переделки архитектуры компонента с частично синхронной обработки на полностью асинхронную.
Причем самым сложным в этой задаче была не столько сама обработка, сколько обосновать ее необходимость перед руководством и показать, что именно она принесет проекту :) Что это дало? В результате мы всё же перешли с ноды 0.10 на последнюю lts 8.11.x. 1. Падения производительности не произошло.
Наоборот, мы получили прирост примерно на 10-15%.
2. Значительно улучшилось потребление памяти, примерно на 30-50% в зависимости от компонента 3. Упомянутые выше «неразрешимые» проблемы разрешились сами собой.
4. Наконец-то у нас появилась возможность использовать новые возможности es6! Хотя по привычке мы ими до сих пор не пользуемся))) Теги: #node.js #сравнение версий #node.js
-
Сравните Dell Alienware M18X И M17X
19 Oct, 24 -
Как Мне Надоел Кальмар С Аудиоплеером
19 Oct, 24 -
Визуальный Раздел The Big Picture
19 Oct, 24 -
Курс Интернет-Маркетинга Джереми Шумейкера
19 Oct, 24 -
Rss И Веб-Импорт Закладок
19 Oct, 24