Настройка TIME_WAIT TCP

Мы пытаемся настроить приложение, которое принимает сообщения через TCP, а также использует TCP для некоторых внутренних сообщений. При тестировании нагрузки мы заметили, что время отклика значительно ухудшается (а затем полностью прекращается), так как в систему поступают больше одновременных запросов. За это время мы видим много TCP-соединений в состоянии TIME_WAIT, и кто-то предложил снизить переменную среды TIME_WAIT от нее по умолчанию 60 секунд до 30.

Из то, что я понимаю, параметр TIME_WAIT по существу устанавливает время, когда ресурс TCP становится доступным для системы снова после того, как соединение замкнутый.

Я не "сетевой парень" и мало знаю об этих вещах. Мне нужно много чего в этом связанном сообщении, но немного "ошалело".

  • Думаю, я понимаю, почему значение TIME_WAIT не может быть установлено на 0, но можно ли его безопасно установить в 5? Что насчет 10? Что определяет "безопасную" настройку для этого значения?
  • Почему значение по умолчанию для этого значения 60? Я предполагаю, что люди намного умнее меня имели веские основания для выбора этого как разумного дефолта.
  • Что еще я должен знать о потенциальных рисках и преимуществах переопределения этой ценности?

Ответ 1

TCP-соединение определяется кортежем (исходный IP-адрес, исходный порт, целевой IP-адрес, порт назначения).

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

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

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

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

Ответ 2

Обычно только конечная точка, которая выдает "активное закрытие", должна перейти в состояние TIME_WAIT. Поэтому, если это возможно, попросите своих клиентов выдать активное закрытие, которое оставит TIME_WAIT на клиенте и НЕ на сервере.

Смотрите здесь: http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html и http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/ (позже также объясняется, почему это не всегда возможно из-за конструкции протокола, которая не учитывает TIME_WAIT).

Ответ 3

Pax правильно объясняет причины TIME_WAIT и почему вы должны быть осторожны при снижении настроек по умолчанию.

Лучшим решением является изменение номеров портов, используемых для исходного конца ваших сокетов. Как только вы это сделаете, вам не придется беспокоиться о времени ожидания отдельных сокетов.

Для прослушивания сокетов вы можете использовать SO_REUSEADDR, чтобы разрешить связывание сокетов, несмотря на разъемы TIME_WAIT.

Ответ 5

настройка tcp_reuse более полезна, чем изменение time_wait, если у вас есть параметр (ядра 3.2 и выше, к сожалению, дисквалифицирует все версии RHEL и XenServer).

Снижение значения, особенно для подключенных к VPN пользователей, может привести к постоянному восстановлению прокси-туннелей исходящего соединения. С конфигурацией по умолчанию Netscaler (XenServer), которая ниже, чем стандартная конфигурация Linux, Chrome иногда должен воссоздавать прокси-туннель до десятка раз, чтобы получить одну веб-страницу. Приложения, которые не повторяются, например Maven и Eclipse P2, просто терпят неудачу.

Исходный мотив для параметра (избегать дублирования) был избыточен с помощью RFID-кода TCP, который указывает включение метки времени во всех TCP-запросах.

Ответ 6

Я тестировал серверное приложение (linux) с помощью тестовой программы с 20 потоками.

В 959 000 циклах соединения/закрытия у меня было 44 000 неудачных соединений и много тысяч сокетов в TIME_WAIT.

Я установил SO_LINGER в 0 до закрытия вызова, а в последующих прогонах тестовой программы не было сбоев подключения и менее 20 сокетов в TIME_WAIT.

Ответ 7

TIME_WAIT не может быть виновником.

int listen(int sockfd, int backlog);

Согласно Unix Network Programming Volume1, backlog определяется как сумма завершенной очереди подключений и неполной очереди соединений.

Скажем, отставание - 5. Если у вас есть 3 завершенных соединения (состояние ESTABLISHED) и 2 неполных соединения (состояние SYN_RCVD), и есть еще один запрос на соединение с SYN. Стек TCP просто игнорирует пакет SYN, зная, что он будет повторно передан в другое время. Это может вызвать деградацию.

По крайней мере, то, что я читал.;)