Какова стоимость многих TIME_WAIT на стороне сервера? - PullRequest
56 голосов
/ 26 ноября 2009

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

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

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

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

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

Ответы [ 6 ]

56 голосов
/ 06 декабря 2009

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

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

12 голосов
/ 27 ноября 2009

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

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

12 голосов
/ 26 ноября 2009

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

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

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

2 голосов
/ 29 августа 2016

Если у вас много соединений с разных 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: таблица заполнена, пакет сбрасывается». и сервер не будет принимать новые входящие соединения, пока в таблице отслеживания снова не будет места.

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

0 голосов
/ 02 мая 2018

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

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

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

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

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

0 голосов
/ 26 ноября 2009

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

...