Почему мой веб-сервер сбрасывает соединения при сбросе TCP при высокой нагрузке?
У меня есть небольшая настройка 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, все эти ошибки являются ошибками "сброса TCP-соединения".
Вот график пропускной способности линоды. Имейте в виду, что это среднее 5-минутное значение, поэтому оно немного фильтруется по нижним частотам (мгновенная пропускная способность, вероятно, намного выше), но, тем не менее, это ничего:
ЦПУ:
I / O:
Вот 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 между службой нагрузочного тестирования и моим сервером?
Спасибо!
4 ответа
Чтобы установить максимальное количество открытых файлов (если это вызывает вашу проблему), вам нужно добавить "fs.file-max = 64000" в /etc/sysctl.conf
Может быть любое количество источников сброса соединения. У нагрузочного тестера могут быть недоступные временные порты, из которых можно инициировать соединение, устройство на пути (например, брандмауэр, выполняющий NAT) может исчерпать свой пул NAT и не может предоставить исходный порт для соединения, если балансировщик нагрузки или брандмауэр на вашем конце, который, возможно, достиг предела соединения? И если сделать исходный NAT на входящем трафике, это также может привести к исчерпанию порта.
Один действительно нужен файл pcap с обоих концов. То, что вы хотите посмотреть, это если попытка подключения отправляется, но никогда не достигает сервера, но все равно выглядит так, как если бы она была сброшена сервером. Если это так, то что-то по линии должно было сбросить соединение. Истощение пула NAT является распространенным источником подобных проблем.
Кроме того, netstat -st может дать вам дополнительную информацию.
Некоторые идеи, которые можно попробовать, основанные на моем недавнем подобном опыте настройки. Со ссылками:
Вы говорите, что это статический текстовый файл. На всякий случай происходит восходящая обработка, очевидно, доменные сокеты улучшают пропускную способность 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: https://stackoverflow.com/questions/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
Пожалуйста, посмотрите, сколько портов в TIME_WAIT
состояние с помощью команды netstat -patunl| grep TIME | wc -l
и изменить net.ipv4.tcp_tw_reuse
до 1.