2009-11-26 2 views
51

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

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

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

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

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

+0

Некоторые системы видят проблемы на «32K' TIME_WAIT' »http://serverfault.com/a/212127/87017 – Pacerier

+1

Для linux есть [бумага] (https://tools.ietf.org/html/draft- faber-time-wait-avoidance-00) на основе данных через Webstone Benchmark. Также «[* Состояние« TIME-WAIT »в TCP и его влияние на занятые серверы *] (https://scholar.google.com/scholar?cluster=2607037814764769062&hl=ru&as_sdt=0,5&sciodt=0,5)». – Pacerier

ответ

48

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

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

+0

Вы уверены, что это относится к Windows Server и другим ОС? – Pacerier

-1

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

+7

Почему сервер заканчивается из портов? Сервер не выделяет локальный порт для принятого соединения. Вот почему сервер может обрабатывать параллельное соединение 100 тыс., В результате чего проблема с загруженным ЦП. – trustin

+4

Реализует локальный порт для принятых соединений, запускает 'netstat -a' из командной строки, и вы увидите их. Я считаю, что причиной TIME_WAIT является то, что TCP-пакеты могут поступать в неправильном порядке, поэтому порт не должен быть немедленно закрыт, чтобы разрешить доступ к поздним пакетам. Это означает, что действительно возможно выйти из портов. Есть способы сократить период TIME_WAIT, но риск состоит в том, что с более короткими таймаутами, а затем посылая пакеты из предыдущего соединения могут быть ошибочно приняты за пакеты из нового соединения на переработанном порту. –

+3

Если вы запустите 'netstat -nat', вы увидите, что соединения, принятые одним и тем же сервером, имеют один и тот же локальный порт. Следовательно, я полагаю, что для принятых соединений не назначены дополнительные локальные порты? – trustin

12

Результаты до сих пор:

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

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

+0

Не уверен, что это правда. Я создал сотни TIME_WAIT, но не видел, как количество открытых файловых дескрипторов увеличивается в sysctl fs.file-nr. – c4il

+0

@ c4il, @ trustin, Почему каждый обсуждает это, не заявляя .. ** какая ОС **?Также были бы полезны конкретные версии. – Pacerier

+0

@trustin: В чем причина многих открытых файловых дескрипторов, вы нашли его? – Albin

9

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

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

2

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

Проверил:

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

Над всем Src IP/порт и Dest IP/Port кортежей вы можете иметь только net.ipv4.netfilter.ip_conntrack_max в таблице отслеживания. Если этот предел ударит, вы увидите сообщение в ваших журналах «nf_conntrack: table full, dropping packet». и сервер не будет принимать новые входящие соединения, пока в таблице отслеживания не останется места.

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

Смежные вопросы