Почему мой веб-сервер сбрасывает соединения при сбросе TCP при высокой нагрузке?

10

У меня есть небольшая настройка VPS с nginx. Я хочу выжать из нее как можно большую производительность, поэтому я экспериментировал с оптимизацией и нагрузочным тестированием.

Я использую Blitz.io для нагрузочного тестирования, получая небольшой статический текстовый файл, и сталкиваюсь с нечетной проблемой, когда сервер, похоже, отправляет сброс TCP, когда число одновременных подключений достигает примерно 2000. Я знаю, что это очень большого количества, но от использования htop у сервера все еще есть много, чтобы сэкономить процессорное время и память, таким образом, я хотел бы выяснить источник этой проблемы, чтобы видеть, могу ли я продвинуть это еще дальше.

Я использую Ubuntu 14.04 LTS (64-разрядную версию) на 2 ГБ Linode VPS.

У меня недостаточно репутации, чтобы публиковать этот график напрямую, поэтому вот ссылка на график Blitz.io:

введите описание изображения здесь

Вот что я сделал, чтобы попытаться выяснить источник проблемы:

  • Значение конфигурации nginx worker_rlimit_nofileустановлено на 8192
  • уже nofileустановлены в 64000 для твердых и мягких ограничений для rootи www-dataпользователя (то , что Nginx работает как) в/etc/security/limits.conf
  • нет никаких признаков того, что что-то идет не так /var/log/nginx.d/error.log(как правило, если вы работаете с ограничениями файловых дескрипторов, nginx выведет сообщения об ошибках, сообщающие об этом)

  • У меня есть настройка UFW, но нет правил ограничения скорости. Журнал UFW указывает, что ничего не блокируется, и я попытался отключить UFW с тем же результатом.

  • Там нет никаких ориентировочных ошибок в /var/log/kern.log
  • Там нет никаких ориентировочных ошибок в /var/log/syslog
  • Я добавил следующие значения /etc/sysctl.confи загрузил их sysctl -pбез эффекта:

    net.ipv4.tcp_max_syn_backlog = 1024
    net.core.somaxconn = 1024
    net.core.netdev_max_backlog = 2000
    

Есть идеи?

РЕДАКТИРОВАТЬ: я сделал новый тест, увеличивая до 3000 подключений на очень маленький файл (всего 3 байта). Вот график Blitz.io:

График Blitz.io

Опять же, согласно Blitz, все эти ошибки являются ошибками «сброса TCP-соединения».

Вот график пропускной способности линоды. Имейте в виду, что это 5-минутное среднее значение, поэтому оно немного фильтруется по нижним частотам (мгновенная пропускная способность, вероятно, намного выше), но, тем не менее, это ничто:

введите описание изображения здесь

ЦПУ:

введите описание изображения здесь

I / O:

введите описание изображения здесь

Вот htopближе к концу теста: HTOP

Я также перехватил часть трафика с помощью tcpdump в другом (но похожем) тесте, запустив перехват, когда начали появляться ошибки: sudo tcpdump -nSi eth0 -w /tmp/loadtest.pcap -s0 port 80

Вот файл, если кто-то хочет взглянуть на него (~ 20 МБ): https://drive.google.com/file/d/0B1NXWZBKQN6ETmg2SEFOZUsxV28/view?usp=sharing

Вот график пропускной способности от Wireshark:

введите описание изображения здесь (Строка - это все пакеты, синие полосы - ошибки TCP)

Из моей интерпретации захвата (и я не эксперт), похоже, что флаги TCP RST приходят из источника нагрузочного тестирования, а не с сервера. Итак, если предположить, что что-то не так со стороны службы нагрузочного тестирования, можно ли с уверенностью предположить, что это является результатом какого-то управления сетью или уменьшения DDOS между службой нагрузочного тестирования и моим сервером?

Спасибо!

Эрик Свон
источник
Ваш провайдер делает какое-то смягчение DDoS? Это может помешать вашему тесту.
Майкл Хэмптон
@MichaelHampton Я совершенно уверен, что Линод не делает этого.
EEAA
Можете ли вы опубликовать график сети с панели управления Linode? Какую пропускную способность фактически занимает этот тест?
EEAA
Я провел немного больше расследований и обновил исходное сообщение с большим количеством информации. Я также подтвердил с Linode, что они не делают смягчение DDOS, хотя это не обязательно означает, что сетевой провайдер между сервисом нагрузочного тестирования и Linode не делает ничего. Спасибо!
Эрик Свон
1
Есть ли причина, по которой вы устанавливаете только net.core.netdev_max_backlog2000? Несколько примеров, которые я видел, имеют его на порядок выше для гигабитных (и 10-гигабитных) соединений.
Моше Кац

Ответы:

1

Может быть любое количество источников сброса соединения. У нагрузочного тестера могут быть недоступные временные порты, из которых можно инициировать соединение, устройство, находящееся в процессе (например, брандмауэр, выполняющий NAT), может исчерпать свой пул NAT и не может предоставить исходный порт для соединения, если балансировщик нагрузки или брандмауэр на вашем конце, который, возможно, достиг предела соединения? И если делать исходный NAT на входящем трафике, это также может привести к исчерпанию порта.

Один действительно нужен файл pcap с обоих концов. То, что вы хотите посмотреть, это если попытка подключения отправляется, но никогда не достигает сервера, но все равно выглядит так, как если бы она была сброшена сервером. Если это так, то что-то в этом направлении должно было сбросить соединение. Истощение пула NAT является распространенным источником подобных проблем.

Кроме того, netstat -st может дать вам дополнительную информацию.

GeorgeB
источник
1

Некоторые идеи, которые можно попробовать, основанные на моих недавних подобных настройках. Со ссылками:

Вы говорите, что это статический текстовый файл. На всякий случай происходит восходящая обработка, очевидно, доменные сокеты улучшают пропускную способность TCP по соединению на основе порта TC:

https://rtcamp.com/tutorials/php/fpm-sysctl-tweaking/ https://engineering.gosquared.com/optimising-nginx-node-js-and-networking-for-heavy-workloads

Независимо от завершения в восходящем направлении:

Включите multi_accept и tcp_nodelay: http://tweaked.io/guide/nginx/

Отключить медленный запуск TCP: /programming/17015611/disable-tcp-slow-start http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

Окно оптимизации перегрузки TCP (initcwnd): http://www.nateware.com/linux-network-tuning-for-2013.html

JayMcTee
источник
1

Чтобы установить максимальное количество открытых файлов (если это вызывает вашу проблему), вам нужно добавить «fs.file-max = 64000» в /etc/sysctl.conf

Sean1e
источник
0

Пожалуйста, посмотрите, сколько портов в TIME_WAITсостоянии, используя команду, netstat -patunl| grep TIME | wc -lи измените net.ipv4.tcp_tw_reuseна 1.

fgbreel
источник
Как бы я посмотрел, сколько портов в TIME_WAITштате?
Эрик Свон
Используя netstatили ss. Я обновил свой ответ с полной командой!
fgbreel
Я перезапустил тест и watch -n 1 'sudo netstat -patunl | grep TIME | wc -l'возвращает 0 на протяжении всего теста. Я уверен, что сброс происходит в результате уменьшения DDOS кем-то между тестером нагрузки и моим сервером, основываясь на моем анализе файла PCAP, который я выложил выше, но если бы кто-то мог подтвердить, что это было бы здорово!
Эрик Свон