Я работаю над несколько необычным приложением, в котором 10 000 клиентов точно рассчитаны на то, чтобы все пытались отправить данные сразу, каждые 3 минуты или около того. Эта команда «ab» довольно точно имитирует один заградительный огонь в реальном мире:
ab -c 10000 -n 10000 -r "http://example.com/submit?data=foo"
Я использую Node.js в Ubuntu 12.4 на VPS-экземпляреackspacecloud для сбора этих материалов, однако я наблюдаю очень странное поведение Node, даже когда я удаляю всю свою бизнес-логику и превращаю http-запрос в no- соч.
Когда тест выполнен примерно на 90%, он зависает на длительный период времени. Странно, но это стабильно происходит на 90% - при c=n=10k, на 9000; для c=n=5k – 4500; для c=n=2k в 18:00. В конце концов тест фактически завершается, часто без ошибок. Но журналы ab и node показывают непрерывную обработку примерно до 80-90% тестового прогона, а затем долгая пауза перед завершением.
Когда узел нормально обрабатывает запросы, загрузка ЦП обычно составляет около 50-70%. В период зависания процессор загружается до 100%. Иногда он остается около 0. Между неустойчивым ответом ЦП и тем фактом, что он кажется не связанным с фактическим количеством подключений (только % завершено), я не подозреваю сборщика мусора.
Я пробовал запускать «ab» на локальном хосте и на удаленном сервере — тот же эффект.
Я подозреваю, что что-то связано со стеком TCP, возможно, с закрытием соединений, но ни одно из моих изменений конфигурации не помогло. Мои изменения:
- улимит -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» перейдет к «Отбрасыванию соединений».
Я предполагаю, что это какая-то проблема с настройкой стека TCP в Linux, и я прочитал почти все, что мог найти в сети. Ничто из того, что я пробовал, не имеет значения. Любой совет?
Обновление: Пробовал с tcp_max_syn_backlog, somaxconn, netdev_max_backlog и параметром невыполненной работы listen(), установленным на 50 КБ, без каких-либо изменений в поведении. По-прежнему выдает предупреждение о SYN-флоде.