Какова стоимость многих TIME_WAIT на стороне сервера?

StackOverflow https://stackoverflow.com/questions/1803566

  •  05-07-2019
  •  | 
  •  

Вопрос

Предположим, есть клиент, который устанавливает множество кратковременных подключений к серверу.

Если клиент закроет соединение, в нем будет много портов. TIME_WAIT состояние на стороне клиента.Поскольку у клиента заканчиваются локальные порты, быстро сделать новую попытку подключения становится невозможно.

Если сервер закроет соединение, я увижу много TIME_WAITs на стороне сервера.Однако приносит ли это какой-либо вред?Клиент (или другие клиенты) могут продолжать попытки подключения, поскольку у него никогда не заканчиваются локальные порты, а количество TIME_WAIT состояние увеличится на стороне сервера.Что произойдет в конце концов?Случилось ли что-то плохое?(замедление, сбой, обрыв соединения и т. д.)

Обратите внимание, что мой вопрос не «Какова цель TIME_WAIT?", а "Что произойдет, если их будет так много? TIME_WAIT состояния на сервере?" Я уже знаю, что происходит, когда соединение закрывается в TCP/IP и почему TIME_WAIT требуется состояние.Я не пытаюсь устранить неполадки, а просто хочу знать, в чем может заключаться потенциальная проблема.

Проще говоря, скажем netstat -nat | grep :8080 | grep TIME_WAIT | wc -l принты 100000.Что случилось бы?Замедляется ли сетевой стек операционной системы?Ошибка «Слишком много открытых файлов»?Или просто не о чем беспокоиться?

Это было полезно?

Решение

Каждый сокет в TIME_WAIT потребляет некоторую память в ядре, обычно несколько меньше, чем сокет ESTABLISHED , но все еще имеет большое значение. Достаточно большое количество может исчерпать память ядра или, по крайней мере, ухудшить производительность, поскольку эта память может использоваться для других целей. Сокеты TIME_WAIT не содержат дескрипторов открытых файлов (при условии, что они были закрыты должным образом), поэтому вам не нужно беспокоиться о «слишком большом количестве открытых файлов». ошибка.

Сокет также связывает этот конкретный IP-адрес и порт src / dst и порт, поэтому его нельзя использовать повторно в течение интервала TIME_WAIT , (Это целевое назначение состояния TIME_WAIT .) Связывание порта обычно не является проблемой, если только вам не нужно повторно подключить одну и ту же пару портов. Чаще всего одна сторона будет использовать эфемерный порт, и только одна сторона будет привязана к хорошо известному порту. Однако очень большое количество сокетов TIME_WAIT может исчерпать эфемерное пространство порта, если вы неоднократно и часто подключаетесь между одними и теми же двумя IP-адресами. Обратите внимание, что это влияет только на эту конкретную пару IP-адресов и не влияет на установление соединений с другими хостами.

Другие советы

Результаты на данный момент:

Даже если сервер закрыл сокет с помощью системного вызова, его файловый дескриптор не будет освобожден, если он перейдет в состояние TIME_WAIT. Дескриптор файла будет освобожден позже, когда состояние TIME_WAIT исчезнет (т.е. через 2 * MSL секунд). Поэтому слишком большое количество TIME_WAIT может привести к ошибке «слишком много открытых файлов» в процессе сервера.

Я считаю, что стек O / S TCP / IP был реализован с правильной структурой данных (например, хэш-таблица), поэтому общее количество TIME_WAIT не должно влиять на производительность стека O / S TCP / IP. Пострадает только процесс (сервер), которому принадлежат сокеты в состоянии TIME_WAIT.

Каждое соединение идентифицируется кортежем (IP-адрес сервера, порт сервера, IP-адрес клиента, клиентский порт). Важно отметить, что каждое из соединений TIME_WAIT (будь то на стороне сервера или на стороне клиента) занимает один из этих кортежей.

С TIME_WAIT на стороне клиента легко понять, почему вы не можете устанавливать больше соединений - у вас больше нет локальных портов. Однако та же проблема относится и к стороне сервера - после того, как у него есть 64 тыс. Соединений в состоянии TIME_WAIT для одного клиента , он не может принимать больше соединений от этот клиент , потому что он не может определить разницу между старым соединением и новым соединением - оба соединения идентифицируются одним и тем же кортежем. В этом случае сервер должен просто отправить обратно RST для новых попыток подключения от этого клиента.

Если у вас много подключений от разных IP-адресов клиентов к IP-адресам серверов, вы можете столкнуться с ограничениями таблицы отслеживания соединений.

Проверять:

sysctl net.ipv4.netfilter.ip_conntrack_count
sysctl net.ipv4.netfilter.ip_conntrack_max

Для всех кортежей src ip/port и dest ip/port в таблице отслеживания может быть только net.ipv4.netfilter.ip_conntrack_max.Если этот лимит достигнут, вы увидите сообщение в своих журналах «nf_conntrack:таблица заполнена, пакет теряется», и сервер не будет принимать новые входящие соединения, пока в таблице отслеживания снова не появится место.

Это ограничение может коснуться вас задолго до того, как закончатся временные порты.

В моем сценарии я запустил сценарий, который несколько раз планирует файлы, мой продукт выполняет некоторые вычисления и отправляет ответ клиенту, т.е. клиент выполняет повторный HTTP-вызов для получения ответа на каждый файл. Когда около 150 файлов являются запланированными портами сокетов в мой сервер переходит в состояние time_wait, и в клиенте выдается исключение, которое открывает http-соединение, т.е.

 Error : [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

В результате мое приложение зависло. Я не знаю, может ли поток потоков перешел в состояние ожидания или что произошло, но мне нужно завершить все процессы или перезапустить приложение, чтобы оно снова заработало.

Я попытался сократить время ожидания до 30 секунд, поскольку по умолчанию оно составляет 240 секунд, но оно не сработало.

Таким образом, в целом общее влияние было критическим, так как мое приложение не отвечало на запросы

похоже, сервер может просто исчерпать порты для назначения входящих соединений (на время существующих TIMED_WAIT) - случай для атаки DOS.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top