Сохранение состояния TIME_WAIT

Сильно загруженные Web-серверы обрабатывают большое количество запросов на создание новых TCP-соединений. Поддержка большого числа ТСР-соедииепий требует большого объема оперативной памяти и приводит к большим накладным расходам при обработке получаемых пакетов. В идеале оиерационная система могла бы освобождать эти ресурсы сразу же, как только соединение закрывается. Но протокол TCP требует, чтобы один или оба комиыотера сохраняли информацию о закрытом соединении. В этом подразделе мы объясним, почему хотя бы один из компьютеров должен сохранять состояние TIME_WAIT и почему ответственность за это обычно ложится не на клиента, а на сервер. Потом мы рассмотрим несколько предложений по снижению накладных расходов, связанных с сохранением состояния TIME_WAIT на Web-cepвepe.

СОХРАНЕНИЕ ИНФОРМАЦИИ О ЗАКРЫВШИХСЯ СОЕДИНЕНИЯХ

Сохранение информации о закрывшихся ТСР-соедипениях приводит к значительным накладным расходам на силыю загруженном Web-сервере. Рассмотрим пример сервера, который закрывает соединение после отправки HTTP-ответа клиенту. Закрытие соединения производится с помощью процедуры, состоящей из четырех шагов и начинающейся передачей пакета FIN, как это описывалось в главе 5 (раздел 5.2.3). При получении пакета FIN, клиент посылает пакет с подтверждением. Потом клиент читает HTTP-ответ. За последним байтом сообщения клиент находит символ копца файла (EOF), который означает, что сервер закрыл свою сто- ропу соединения. Клиент затем закрывает свою сторону соединения, посылая при этом пакег FIN серверу. Получив пакет FIN от клиента, сервер посылает ACK, завершающий четырехшаговую процедуру. Получение подтверждающего пакета ACK сообщает клиенту, что соединение закрыто. Но в то же время сервер не может зпать, дошло ли его подтверждение до клиента или нет.

Предположим, что последний пакет ACK от сервера был утерян в сети, как показано на рис. 8.4. Если пакет ACK был потеряп, то клиент, в конце концов, запустит таймер повторной передачи, но истечению которого он снова пошлет пакет FIN. При потере этого пакета клиент снова запустит таймер повторной передачи, после чего сиова пошлет иакет FIN. Так как сервер не знает, дошел ли его пакет ACK по назначению или нет, то сервер не может решить, падо ли передавать ли его спова. Поэтому сервер не может удалить информацию о соединении в течение некоторого времени. Предположим, что сервер все-таки удалил информацию о соединении, некорректно полагая, что клиент получил его пакет ACK. Позже, когда от клиента приходит повторный пакет FIN, сервер не сможет попять, что этот пакет относится к только что закрытому соединению. Думая, что пакет FIN был послан по ошибке, сервер пошлет клиенту пакег RST вместо того, чтобы спова послать подтверждающий пакет ACK.

Рис 8.4. Потеря и повторная передача заключительного АСК-пакета сервером

Более серьезная ситуация складывается, если один или более пакетов, относящихся к данному соединению, продолжают путешествовать но сети. Предположим, что сервер получил запрос целиком, а клиент получил ответ полностью. Какой-ни- будь новторпо отправленный пакет может еще по разным причинам оставаться в сети. Это случается, если иакет был передай более одного раза, причем одна копия дошла до адресата, а другая продолжала блуждать по сети. Такой иакет может, в конце концов, добраться до адресата. Обработка повторного пакета зависит от состояния соединения между компьютерами:

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

•          Соединение было закрыто и нет нового соединения. Предположим, что старое соединение было закрыто, а новое соединение не было установлено. Когда пакет приходит, операционная система получателя просматривает номера портов TCP в заголовке пакета, чтобы определить, к какому соединению он относится. Не пайдя такого соединения, получатель также отбрасывает пакет.

•          Соединение было закрыто, а новое соединение создано. Предположим, что соединение было закрыто, и Компьютеры создали повое соединение с той же парой номеров портов. Когда повторпый пакет прибывает, номера портов анализируются операционной системой получателя. Номера портов пакета совпадают с номерами портов нового соединения, и данные передаются приложению, связанному с повым соединением. Это ошибочно, гак как этот пакет не принадлежит новому соединению.

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

Чтобы предотвратить создапие нового соединения с теми же номерами портов, хотя бы один из компьютеров должен помнить о существовании предыдущего соединения. Спецификация TCP возлагает эту обязанность на Компьютер, который первым послал пакет FIN. На этом компьютере ТСР-соедипеиие переходит в состояние TIME_WAIT. Операционная система сохраняет информацию, связанную с соединением, чтобы в случае необходимости иовторио передать заключительный пакет ACK и предотвратить создание нового соединения с теми же номерами портов. Соедипеиие должно оставаться в состоянии TIME_WAIT столько времени, сколько нужно для того, чтобы в сети не осталось ни одного накета, принадлежащего данному соединению. Выполнить это очень сложно, так как протокол IP не вводит ограничений на время пребывания пакета в пути. На практике поле в заголовке IP-пакета, содержащее время его жизни (TTL), должно ограничивать время пребывания пакета в сети, как это описано в главе 5 (раздел 5.1.4). Это 8-битное поле позволяет задавать максимальное значение TTL в 255 секунд.

TCP требует, чтобы Компьютер оставался в состоянии TIME_WAIT в течение двух периодов максимального времени жизни сегмента (MSL — maximum segment lifetime) — оценки времени наибольшей задержки при доставке пакетов. В спецификации TCP указывается, что реализации протокола должпы использовать зпачепие MSL, равное двум минутам U-81J, хотя на практике различные реализации используют 30 секунд, одну минуту или две минуты. С одной стороны, малое значение MSL уменьшает длительность состояния TIME_WAIT, что в свою очередь умепьшаег объем системных ресурсов, необходимых для хранения информации о закрытых соединениях. Однако небольшое значение MSL увеличивает вероятность того, что повторпые пакеты остаются в сети. Кроме того, небольшое значение MSL уменьшает вероятность того, что отправитель сумеет повторно выслать утерянный заключительный пакет ACK. С другой стороны большое значение MSL приводит к гому, что состояние TIME_WAIT длится дольше. В результате, достаточно много соединений могут оказаться в состоянии TIME_WAIT одновременно, что приводит к увеличению требований к системным ресурсам на силыю загруженном сервере. Необходимо также отметить, что большие значения MSL ограничивают скорость взаимодействия между Компьютерами.

Предположим, что клиент создает соединение по порту 1025 с сервером, функционирующим на удаленном компыогере на порту 80. После передачи пакета FIN для закрытия ТСР-соединения сервер переходит в состояние TIME_WAIT на четыре минуты. Получив подтверждение ACK от сервера, клиент завершает соединение. Клиент может попытаться установить новое соединение с тем же сервером, чтобы запросить другой ресурс. Это соединение должпо использовать другой клиентский порт (например, 1026), потому что сервер все еще находится в состоянии TIME_WAIT из-за завершенного соединения. Заголовок TCP пакета имеет 16-бит- пое поле номера порта, что ограничивает число различных портов, которое клиент может использовать для соединения. На практике это не приводит к ограничениям возможностей браузера. Но вот прокси-серверу Обычно нужно устанавливать соединения с популярными серверами с очепь высокой частотой. Ограничение становится еще более серьезным, если прокси-сервер должен передавать все запросы другому прокси-серверу. Невозможность создавать новые соединения со старыми номерами портов ограничивает скорость, с которой прокси-сервер может посылать запросы следующему прокси-серверу в цепочке.

ВЛИЯНИЕ TIME_WAIT НА WEB-CEPBEPbI

Web-серверы часто инициируют закрытие соединений, что обусловливает дополнительные накладные расходы, связанные с поддержанием состояния TIME_WAIT. Сначала рассмотрим случай, когда клиеиг и сервер не поддерживают долговременного соединения. В такой ситуации сервер обычно закрывает соединение (посылая пакет FIN) сразу после отсылки HTTP-ответа клиенту. Теперь рассмотрим другую ситуацию, когда клиент и сервер поддерживают соединение открытым. В этом случае все равно наступает момент, когда либо клиент, либо сервер закрывают соединение. Обычно сервер имеет больше причин закрыть соединение. Например, загруженный Web-cepвep не может позволить себе поддерживать долговременные соединения с каждым клиентом. Серверы обычно используют таймеры на прикладном уровне для закрытия соедииепий после некоторого периода бездействия, как будет рассмотрено позже, в разделе 8.4.2. Браузер, иаиротив, имеет достаточно мало поводов закрыть соединение, нотому что использование долговременного соединения позволяет избежать задержек, связаипых с созданием нового соединения.

В любом из перечисленных сценариев первым закрывает соединение сервер и, соответственно, оп и должен поддерживать состояние TIME_WAIT. Ситуация осложняется, если клиентом является ирокси-сервер. Интенсивно функционирующий прокси-сервер связан ТСР-соединениями с большим числом клиентов и серверов. У ирокси-сервера столько же причин закрыть соединение, сколько и у Web-сервера, если не больше. Если прокси-сервер закрывает соединение, то он и должен поддерживать состояние TIME_WAIT, а не Web-сервер. Поддержка co- тояний TIME_WAIT сильпо влияет на производительность прокси-серверов. В общем случае TIME_WAIT представляет собой неудачпый компромисс, так как загруженные компьютеры должны закрывать соединения и в то же время поддерживать состояние TIME_WAIT.

Дополнительная нагрузка, обусловленная TIME_WAIT, увеличивается еще и за счет того, что ТСР-соединения — достаточно коротки, гак как большинство Web-ответов относительно невелики. Предположим, что клиент запрашивает одиночный ресурс с Web-cepвepa. Сервер тратит несколько секунд, отвечая на этот запрос. После закрытия соединения сервер находится в состоянии TIME_WAIT в течение четырех минут. Это гораздо больше времени соединения. Более ранние Internet-приложения, такие как Telnet или FTP, обычно использовали ТСР-соеди- пения в течение более долгого времени. По сравнению с FTP-сервером, HTTP-cepвер большую часть времени находится в состоянии TIME_WAIT. Использование долговременных соединений частично решает эту проблему. Использование одного соединения для нескольких НТТР-запросов уменьшает общее число как открытых, так и закрытых соединений на сервере. А эго, в свою очередь, уменьшает количество соединений, находящихся в состоянии TIME_WAIT. И, тем не менее, интенсивно работающему Web серверу все равпо приходится поддерживать достаточно мпо- го соединений в состоянии TIME_WAIT.

УМЕНЬШЕНИЕ НАГРУЗКИ, СВЯЗАННОЙ С СОСТОЯНИЕМ TIME_WAIT

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

К счастью, операционной системе необходимо хранить меньше информации о соединениях в состоянии TIME_WAIT, чем об акгивпых соединениях. В современных операционных системах требования к памяти, необходимой для повторпой передачи последнего пакета ACK и для предотвращения создания соединения с теми же IP-адресами и номерами портов, снижены до минимума. Большое число соединений в состоянии TIME_WAIT увеличивает также ресурсы, необходимые для проверки таймеров, например, таймера повторпой передачи. Многие операционные системы проверяют состояния таймеров, периодически сканируя список TCP-соединений. Перенося соединения в состоянии TIME_WAIT в конец списка, операционная система уменьшает время, требуемое для сканирования списка. Уменьшение затрат процессорного времени и памяти на соединения в состоянии TIME_WAIT приводят к заметпому увеличению производительности Web-серверов [AD99].

Несмотря на достигнутое уменьшение затрат процессорного времени и памяти, соединения в состоянии TIME_WAIT все равпо могут привести к перегрузке Web-серверов. Предлагаются несколько методов переложить ответственность за обработку состояния TIME_WAIT на клиента [FTY99], который, как предполагается, работает с небольшим числом соединений.

• Внесение изменений в TCP. Спецификация TCP может быть изменена таким образом, чтобы обработку состояния TIME_WAIT производил получатель первого пакета FIN. Например, Web-сервер закрывает соединение и посылает клиенту пакет FIN. Получив пакет FIN, клиент переходит в состояние TIME_WAIT. Чтобы убедиться в том, что сервер не находится в состоянии TIME_WAIT, клиент может послать серверу пакет RST (рис. 8.5). Получение RST заставляет сервер покинуть состояние TIME_WAIT и освободить ресурсы, отведенные для соединения. Альтернативный подход представляет собой модификацию процедуры установления соединения так, чтобы клиент и сервер договаривались, кто будет обрабатывать TIME_WAIT при закрытии соединения.

Рис 8.5. Клиент посылает RST, чтобы освободить сервер от необходимости поддержки состояния TIME_WAIT

• Внесение изменений в HTTP. Спецификация HTTP может быть измепеиа таким образом, что закрытие соединения должен инициировать клиент, а не сервер. Например, повый заголовок ответа может содержать инструкцию клиенту закрыть соединение после получения ответа. Новый заголовок запроса может позволить клиенту нринять на себя ответственность за закрытие соединения. Например, клиент может закрыть соединение автоматически, скачав встроенные в HTML-страницу изображения. Правда, отдавать управление соединением клиенту — не всегда подходящее Решение. Клиент может иметь веские причины не закрывать соединение или не принимать на себя ответственность за обслуживание состояния TIME_WAIT.

И тот, и другой способ требуют впесепия измепепий в спецификации либо TCP, либо HTTP. Ни один из предложенных подходов не предоставляет привлекательного решения проблемы. Вместо этого администраторы загруженных Web-cepверов вносят изменения в настройки операционной системы так, чтобы уменьшить длительность состояния TIME_WAIT (например, до 5 секупд). Это уменьшает па- грузку, связанную с поддержанием состояния TIME_WAIT, увеличивая тем самым вероятность создания соединение с теми же номерами портов.

Источник: Web-протоколы. Теория и практика. — M.: ЗАО «Издательство БИНОМ», 2002 г. – 592 c.: ил.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100