Перейти к содержимому

Node.js под большим трафиком

09/02/2011

Топик с «числом Бумбурума», хоть и привёл к моему бану на Хабре, позволил на несколько часов подставить реальный сайт на Express под большой трафик. Результат интересный: сайт один раз упал, выдав ошибку открытия файла, но после перезапуска node работал нормально. Трафик за пару часов составил около 27000 просмотров, с очень быстрым ростом (выход топика на главную). К сожалению трафик по часам из Google Analytics получить похоже нельзя, было бы более наглядно.

Setup

Сервер крутился на одном виртуальном сервере от Scalaxy. Параметры: 16 ядер по 2.6 Ghz, 512MB оперативки. Операционка: Debian 5. Вообще многоядерность мне особо не потребовалась (по моему Connect сейчас не масштабируется автоматически), оперативной памяти тоже вполне хватило.

Node.js использовалась версии 0.2.6, последние версии Express и Connect из npm, коннектор redis оттуда же. Саму ноду держала на плаву связка Init+Monit. Сайт был набросан на скорую руку, просто чтобы представить собранные данные в удобном виде. Я решил не использовать шаблонизатор чтобы ничего не читалось с диска. Все страницы довольно простые, поэтому я просто на лету подставлял туда нужные данные из Redis и отправлял пользователю. Полный исходный код сайта можно найти здесь. Кстати, валидацию введенных данных я сделать забыл (кроме проверки существования пользователя в Redis), но проблем от этого насколько я знаю не было.

Падение

Когда трафик резко рванул вверх, я держал открытым окно консоли и отслеживал прогресс. Вообще говоря отслеживал я только одно: лог Monit, куда он написал бы о перезапуске ноды при её недоступности. В браузере я изредка обновлял сайт чтобы убедиться что показывается именно то что нужно. И вот, после очередного нажатия Ctrl+F5 я увидел следующий текст:

Error: EMFILE, Too many open files
    at net:908:19
    at Object.lookup (dns:136:5)
    at Stream.connect (net:903:9)
    at Object.createConnection (net:611:5)
    at Object.createClient (/usr/local/lib/node/.npm/redis/0.5.2/package/index.js:607:22)
    at Object. (/root/boomburum/server.js:99:27)
    at param (/usr/local/lib/node/.npm/connect/0.5.7/package/lib/connect/middleware/router.js:147:21)
    at pass (/usr/local/lib/node/.npm/connect/0.5.7/package/lib/connect/middleware/router.js:163:10)
    at Object.router [as handle] (/usr/local/lib/node/.npm/connect/0.5.7/package/lib/connect/middleware/router.js:169:6)
    at next (/usr/local/lib/node/.npm/connect/0.5.7/package/lib/connect/index.js:218:15)

Вначале я подумал что отвалилось что то внутри Connect’а (из за упоминаний middleware), о чём я успел написать в твиттер. Так как времени разбираться особо не было, я просто перезапустил ноду вручную, через Init. После этого происшествий не было.

Потом я всё таки присмотрелся к ошибке и увидел что упало всё в middleware, но упало всё в коннекторе Redis при попытке подключения к Redis-серверу. Банально закончились открытые файлы. Позже я заглянул в лог Redis и увидел что в пиковый момент было одновременно открыто 879 соединений.

Я проверил максимальное количество открытых файлов: ulimit -a показал 1024. Маловато. Выставил ulimit -n 30000, теперь нода не должна падать при большом количестве соединений. Остался всего один вопрос: почему при доступе к Redis-серверу на той же машине происходил DNS lookup. Но, полагаю, с этим можно справиться явно передавая IP и порт сервера.

Ссылки по теме

10 комментариев
  1. Спасибо за статьи 🙂 Очень интересно было почитать про реальное использование нода.

    • Да, мне тоже было интересно его подставить, так сказать, под реальный удар 🙂 Express — вообще отличная штука, как оказалось.

  2. maga permalink

    Спасибо за эксперимент, Сергей!

    512 мб для ноды и редиса при 27к просмотров — это круто. Инстанс ноды же один был запущен, значит только одно ядро было задействовано?

  3. А как нагрузка там, load average, CPU и пр? Сколько памяти было занято?

    • Каюсь, не засёк. Замерял только потребление памяти Redis’ом, было ~37 метров (это уже под нагрузкой).

      • Ну в общем то если 27000 просмотров за пару часов то запросов в секунду

        27000.0/2/60/60=3.75

        Понятно что в пике больше гораздо, но все равно не супер-хайлоад.

        А что, с хабра совсем выпилили или временный бан? Как-то объяснили?

        • Я сейчас пытаюсь найти какой нибудь лог, чтобы посмотреть запросы внутри суток (почему то был уверен что у Google Analytics есть такая возможность). Пока есть только лог Redis’а, может по нему что то удастся восстановить.

          Да, с Хабра меня выпилили полностью. Официальная причина: «троллит и по собственному признанию использует хабр для развлечения».

  4. В ГА это можно сделать либо кастом-отчетом, либо зайдя в раздел ПОСЕТИТЕЛИ ->ПОСЕЩЕНИЯ и там сверху над графиком справа нажать на ЦИФЕРБЛАТ )))

    • Спасибо, нашёл 🙂 Да, там действительно неслабый скачок по посетителям (с 210 до 2800). Видимо тогда и кончились соединения.

Ответить на kuroikaze85 Отменить ответ