Нормальное профилирование node.js приложений

    Предисловие


    Одним из камней преткновения при разработке на node.js является более сложная, по сравнению с другими современными языками, отладка. Из-за асинхронной структуры кода в большом приложении найти утечку памяти или место интенсивного использования процессора становится затруднительно без специализированных утилит. В разное время для node.js уже создавались инструменты профилирования, но большинство из них либо просто не достаточно удобные, либо перестали поддерживаться разработчиками.

    Поиски


    Долгое время я обходился консервативными методами отладки в виде периодического вывода объёма используемой памяти и времени выполнения критических участков кода в консоль, но настал момент, когда необходимость наличия качественного инструмента встала очень остро.

    Первым делом я решил посмотреть не оправился ли node-inspector, который после перехода на node.js 0.6.x перестал поддерживать профилирование CPU и Heap. Оказалось, что в новой версии node-inspector неработающий профайлинг окончательно исключён и теперь это просто debugger. Немного покопавшись в коде старой версии, мне всё же удалось завести профилирование CPU и Heap на node 0.8.x, однако это решение не было идеальным. Чтобы вывести его из состояния «поделки» необходимо было бы заменить устаревший интерфейс WebKit-консоли на современный, переписав приличное количество кода и исправить некоторые проблемы производительности. В целом, решение на основе консоли WebKit мне кажется очень не гибким, поэтому я бросил эту затею и продолжил поиски.

    Вот оно


    Попробовав ещё несколько различных вариантов, я наткнулся на сервис https://nodetime.com. Это инструмент совершенно другого уровня, который гораздо больше других подходил на роль «того самого» идеального инструмента. Сервис состоит из двух частей:
    • backend — собирает подробную статистику о работе приложения;
    • frontend — собственно сам сервис, отображающий эту статистику в понятном для человека, красивом виде.

    Кроме самых необходимых инструментов профилирования CPU и Heap, nodetime содержит набор метрик, существенно упрощающих разработку. Очень порадовала простота и доступность использования сервиса. Для начала работы достаточно просто подключить модуль nodetime к проекту.

    Кроме сбора и отображения статистики в реальном времени nodetime предоставляет возможность сохранять и просматривать статистику за определённые промежутки времени, а также, настраивать уведомления на определённые события (например: утечка памяти).

    Хочется большего


    Безусловно, nodetime сервис очень удобный, но далеко не всегда существует возможность удалённой отладки приложения. Для многих очень остро стоит вопрос конфиденциальности собираемых профайлером данных, да и возможность отладки без подключения к сети совершенно не лишняя.

    Т.к. backend nodetime распространяется по лицензии MIT, за что огромное спасибо его автору, я решил создать на его основе интерфейс, который можно было бы использовать локально. Потратив полторы недели свободных вечеров на разбор протокола и реализацию интерфейса я получил стабильную версию, которую не стыдно показать людям. Встречайте…

    Look


    Для начала демо:
    Тут запущен пример реализации чата.
    А тут можно посмотреть на работу профайлера.

    Внимание: демо запущено на слабом VPS, большая просьба не устраивать хардкор, чтобы все смогли посмотреть.

    Исходный код проекта расположен на GitHub. Добавить модуль в своё приложение можно при помощи npm.

    npm install look
    

    Для работы модуля достаточно подключить его к приложению и, при желании, указать порт и интерфейс, на которых будет работать профайлер. По умолчанию профайлер запускается на порту 5959 и слушает интерфейс '0.0.0.0'.

    Простой пример:

    require('look').start(3131);
    
    var http = require('http');
    http.createServer(function (req, res) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World\n');
    }).listen(8080, '0.0.0.0');
    console.log('Server running at http://0.0.0.0:8080/');
    

    После запуска приложения, профайлер будет доступен на порту 3131 вашего сервера.

    За работу интерфейса отвечает небольшое приложение на основе connect, которое запускается в отдельном потоке, чтобы не влиять на работу основного приложения.

    Заключение


    Это первая стабильная версия look, реализующая самый необходимый функционал. По мере необходимости look будет улучшаться, есть куда расти. Надеюсь, этот инструмент поможет вам писать свои node.js приложения лучше.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 11

      +2
      По классике жанра нужна ссылка на работающую демку.
        0
        Добавил демо в пост.
        +1
        По-моему, очень годное начинание, спасибо, автор!

        • UFO just landed and posted this here
            +1
            Потрясающе, просто потрясающе! Огромное спасибо!
              0
              Попробовал воспользоваться обнаружил багу — на главной странице мониторинга при очередном request (если включен мониторинг) схлопываются раскрытые элементы
                0
                а вообще — хорошая работа, спасибо!
                  0
                  Да, я знаю об этой проблеме. За это поведение отвечает Kendo UI, который я использовал для визуализации данных. Параметров запрещающих схлопывание открытых веток, при добавлении новых я не нашёл. Видимо придётся запоминать открытые ветки и при добавлении новых вызывать их открытие.
                  0
                  мило. А можно подключить к уже запущенному приложению? Какой оверхед?
                    0
                    К уже запущенному подключить не получится. Про оверхед можно прочитать тут: https://nodetime.com/docs#overhead. Оверхед довольно большой при включенном мониторинге транзакций, т.к. там считывается stack-trace. С выключенным мониторингом должно быть поживее, но конкретных бенчмарков пока нет.
                    0
                    Возможно кого-то заинтересует такой подход к профилировке node.js:
                    image

                    Only users with full accounts can post comments. Log in, please.