Какова стоимость много времени ожидания на стороне сервера?
предположим, что есть клиент, который делает много краткосрочных подключений к серверу.
если клиент закрывает соединение, в TIME_WAIT состояние на стороне клиента. Поскольку у клиента заканчиваются локальные порты, становится невозможным быстро выполнить новую попытку подключения.
если сервер закроет соединение, я увижу много TIME_WAITs на стороне сервера. Но разве это приносит какой-то вред? Клиент (или другие клиенты) может держать делая попытки подключения, так как он никогда не заканчивается из локальных портов, и количество TIME_WAIT состояние будет увеличиваться на стороне сервера. Что происходит в конечном итоге? Что-то плохое случилось? (замедление, сбой, сброшенные соединения и т. д.)
обратите внимание, что мой вопрос не "Какова цель TIME_WAIT?"но" что произойдет, если их будет так много TIME_WAIT состояния на сервере?"Я уже знаю, что происходит, когда соединение закрывается в TCP / IP и почему государство. Я не пытаясь беспокоить его, но просто хочу знать, в чем потенциальная проблема с ним.
проще говоря, скажем netstat -nat | grep :8080 | grep TIME_WAIT | wc -l печать 100000. Что будет дальше? Замедляется ли сетевой стек O/S? Ошибка "слишком много открытых файлов"? Или просто не о чем беспокоиться?
6 ответов:
каждый сокет в
TIME_WAITпотребляет некоторую память в ядре, обычно несколько меньше, чемESTABLISHEDсокет все еще значителен. Достаточно большое количество может истощить память ядра или, по крайней мере, снизить производительность, поскольку эта память может использоваться для других целей.TIME_WAITсокеты не содержат открытых файловых дескрипторов (при условии, что они были закрыты должным образом), поэтому вам не нужно беспокоиться об ошибке "слишком много открытых файлов".гнездо также связывает это особенно
src/dstIP-адрес и порт, так что он не может быть повторно использован в течениеTIME_WAITинтервал. (Это и есть предназначениеTIME_WAITгосударство.) Привязка порта обычно не является проблемой, если вам не нужно повторно подключить a с той же парой портов. Чаще всего одна сторона будет использовать эфемерный порт, причем только одна сторона привязана к хорошо известному порту. Однако, очень большое количествоTIME_WAITсокеты могут исчерпать эфемерное пространство порта, если вы неоднократно и часто подключение между теми же двумя IP-адресами. Обратите внимание, что это влияет только на эту конкретную пару IP-адресов и не влияет на установление соединений с другими хостами.
выводы до сих пор:
даже если сервер закрыл сокет с помощью системного вызова, его файловый дескриптор не будет освобожден, если он переходит в состояние TIME_WAIT. Дескриптор файла будет выпущен позже, когда состояние TIME_WAIT исчезнет (т. е. после 2*MSL секунд). Поэтому слишком много TIME_WAITs, возможно, приведет к ошибке "слишком много открытых файлов" в процессе сервера.
Я считаю, что стек TCP/IP O/S был реализован с правильной структурой данных( например, хэш-таблица), поэтому общее число TIME_WAITs не должно влиять на производительность стека O/S TCP/IP. Пострадает только процесс (сервер), которому принадлежат сокеты в состоянии TIME_WAIT.
каждое соединение идентифицируется кортежем (IP сервера, порт сервера, IP клиента, порт клиента). Главное, что
TIME_WAITсоединения (независимо от того, находятся ли они на стороне сервера или на стороне клиента) занимают один из этих кортежей.С
TIME_WAITs на стороне клиента легко понять, почему вы не можете больше подключаться - у вас больше нет локальных портов. Однако та же проблема применяется на стороне сервера - как только он имеет 64K соединений вTIME_WAITstate для одного клиент, он не может принимать больше соединений от клиента, потому что он не может определить разницу между старым соединением и новым соединением - оба соединения идентифицируются одним и тем же кортежем. Сервер должен просто отправить обратноRSTs для новых попыток подключения от этого клиента в этом случае.
Если у вас есть много соединений от многих различных клиентских IP-адресов к серверным IP-адресам, вы можете столкнуться с ограничениями таблицы отслеживания соединений.
проверка:
sysctl net.ipv4.netfilter.ip_conntrack_count sysctl net.ipv4.netfilter.ip_conntrack_maxнад всеми кортежами src ip / port и dest ip / port вы можете иметь только сеть.протокол IPv4.netfilter.ip_conntrack_max в таблице отслеживания. Если этот предел будет достигнут, Вы увидите сообщение в своих журналах " nf_conntrack: таблица полная, отбрасывая пакет."и сервер не будет принимать новые входящие соединения до есть место в таблице отслеживания.
это ограничение может ударить вас задолго до того, как эфемерные порты закончатся.
в моем сценарии я запустил скрипт, который планирует файлы повторно, мой продукт делает некоторые вычисления и отправляет ответ клиенту, т. е. клиент делает повторяющийся http-вызов, чтобы получить ответ каждого файла.Когда около 150 файлов запланированных портов сокета на моем сервере переходит в состояние time_wait и исключение выдается в клиенте, который открывает http-соединение ie
Error : [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permittedв результате мое приложение зависло.Я не знаю, может быть, threadshave ушел в состояние ожидания или что имеет произошло, но мне нужно убить все процессы или перезагрузить приложение, чтобы сделать его работать снова.
Я попытался уменьшить время ожидания до 30 секунд, так как это 240 секунд по умолчанию, но это не сработало.
Так что в основном общее воздействие было критическим, поскольку это сделало мое приложение не реагирующим
похоже, что сервер может просто запускать порты для назначения входящих соединений (на время существующих TIMED_WAITs) - случай для атаки DOS.
Comments