Node.js борется с множеством одновременных подключений
Я работаю над несколько необычным приложением, в котором 10 000 клиентов точно рассчитаны на то, чтобы все пытались отправить данные сразу, каждые 3 минуты или около того. Эта команда 'ab' довольно точно имитирует один заграждение в реальном мире:
ab -c 10000 -n 10000 -r "http://example.com/submit?data=foo"
Я использую Node.js в Ubuntu 12.4 на экземпляре rapspacecloud VPS для сбора этих представлений, однако я наблюдаю очень странное поведение из Node, даже когда я удаляю всю свою бизнес-логику и превращаю запрос http в запрет соч.
Когда тест завершен на 90%, он зависает в течение длительного периода времени. Странно, это происходит последовательно на 90% - для c=n=10k, на 9000; для c=n=5k при 4500; для c=n=2k в 1800. Тест фактически завершается в конце концов, часто без ошибок. Но как журналы ab, так и журналы узлов показывают непрерывную обработку примерно до 80-90% тестового прогона, а затем длительную паузу перед завершением.
Когда узел обрабатывает запросы нормально, загрузка процессора обычно составляет около 50-70%. В течение периода зависания процессор уходит до 100%. Иногда он остается около 0. Между ошибочным откликом процессора и тем фактом, что он не связан с фактическим количеством соединений (только% выполненных), я не подозреваю сборщика мусора.
Я пробовал запустить 'ab' на локальном хосте и на удаленном сервере - тот же эффект.
Я подозреваю, что что-то связано со стеком TCP, возможно, связано с закрытием соединений, но ни одно из моих изменений конфигурации не помогло. Мои изменения:
- ulimit -n 999999
- Когда я слушаю (), я устанавливаю отставание в 10000
Sysctl изменения:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_orphans = 20000
net.ipv4.tcp_max_syn_backlog = 10000
net.core.somaxconn = 10000
net.core.netdev_max_backlog = 10000
Я также заметил, что я склонен получать это сообщение в журналах ядра:
TCP: Possible SYN flooding on port 80. Sending cookies. Check SNMP counters.
Я озадачен этим сообщением, поскольку очередь журнала ожидания TCP должна быть достаточно глубокой, чтобы никогда не переполняться. Если я отключаю файлы cookie cookie, "Отправка файлов cookie" переходит к "Отключение соединений".
Я предполагаю, что это какая-то проблема настройки стека TCP в Linux, и я прочитал почти все, что я мог найти в сети. Ничто из того, что я пробовал, не имеет значения. Любой совет?
Обновление: Пробовал с tcp_max_syn_backlog, somaxconn, netdev_max_backlog и параметром backlog listen(), установленными в 50k, без изменений в поведении. По-прежнему выдает предупреждение SYN также.
2 ответа
Вы используете ab на том же компьютере, где работает узел? Если нет, у вас есть 1G или 10G NIC? Если да, то разве вы не пытаетесь обработать 20 000 открытых соединений?
Также, если вы меняете net.core.somaxconn
до 10000 у вас совершенно нет других открытых сокетов на этой машине? Если вы это сделаете, то 10000 недостаточно.
Вы пытались использовать nodejs
кластер, чтобы распространить количество открытых соединений на процесс?
Я думаю, что вы могли бы найти этот пост, а также предыдущие полезные
http://blog.caustik.com/2012/08/19/node-js-w1m-concurrent-connections/