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

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

Если клиент закрывает соединение, в состоянии 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? Ошибка "Слишком много открытых файлов"? Или просто не о чем беспокоиться?

Ответ 1

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

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

Ответ 2

Выводы:

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

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

Ответ 3

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

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

Ответ 4

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

Check:

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: table full, dropping packet". и сервер не будет принимать новые входящие соединения, пока в таблице отслеживания не останется места.

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

Ответ 5

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