Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Высокопроизводительный сетевой стек Chrome

Глава 1 из книги "Производительность приложений с открытым исходным кодом".

Оригинал: High Performance Networking in Chrome
Автор: Ilya Grigorik
Перевод: А.Панин

Чем является современное веб-приложение?

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

Проект HTTP Archive отслеживает развитие веб-пространства и может помочь нам с ответом на поставленный вопрос. Вместо обхода веб-пространства в поисках данных, он периодически обходит наиболее популярные сайты для записи и сбора аналитических данных об объемах используемых ресурсов, типах данных, заголовках и других метаданных для каждого отдельного узла. Статистика на январь 2013 года может удивить вас. Средняя страница, выбранная из страниц с 300000 узлов из глобальной сети характеризуется следующими параметрами:
  • имеет размер 1280 Кб
  • состоит из 88 ресурсов
  • соединяется более чем с 15 удаленными узлами

Давайте задумаемся над этим. В среднем страница имеет размер 1 Мб и состоит из таких 88 ресурсов, как изображения, сценарии JavaScript и таблицы стилей CSS, доставляемых с 15 различных локальных и удаленных узлов. Более того, каждый из этих показателей неуклонно увеличивался в течение нескольких последних лет, причем на данный момент нет признаков завершения описанного процесса. Мы постоянно создаем все более масштабные и амбициозные веб-приложения.

Простые математические операции, произведенные над данными проекта HTTP Archive позволяют выяснить, что в среднем ресурс имеет размер 15 Кб (1280 Кб / 88 ресурсов), а значит, передачи данных по сети браузеру по большей части имеют кратковременный и пульсирующий характер. Это обстоятельство приводит к появлению дополнительного набора усложнений, так как используемый транспортный протокол (TCP) оптимизирован для осуществления долговременной потоковой передачи данных. Давайте представим себе процесс очистки лука и рассмотрим один из таких сетевых запросов.

Жизнь запроса ресурса в сети

Спецификация временных характеристик навигации от организации W3C описывает API браузера и методы визуализации времени работы и производительности механизмов в процессе жизни каждого запроса в рамках браузера. Давайте рассмотрим используемые в данном случае компоненты, так как каждый из них является критически важным элементом реализации оптимальных пользовательских качеств:

Временные характеристики навигации
Рисунок 1.1 - Временные характеристики навигации

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

При наличии имени узла и пути к ресурсу Chrome в первую очередь проверяет наличие существующих открытых соединений, которые могут быть повторно использованы - сокеты находятся в пуле и идентифицируются параметрами {scheme, host, port} ({схема, узел, порт}). В противном случае, когда вы осуществили настройку прокси-сервера или используете сценарий автоматической настройки прокси-сервера (proxy auto-config - PAC), Chrome проверяет наличие соединений, установленных через подходящий прокси-сервер. Сценарии автоматической настройки прокси-сервера позволяют использовать различные прокси-серверы в зависимости от строки URL ресурса или других заданных правил, причем каждый из серверов может иметь свой собственный пул сокетов. Наконец, если никакие из описанных ранее условий не выполняются, запрос должен начинаться с получения IP-адреса узла на основе его имени - эта операция также известна как разрешение имени узла с использованием сервера DNS.

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

Трехэтапное рукопожатие
Рисунок 1.2 - Трехэтапное рукопожатие

После установления IP-адреса Chrome может открыть новое соединение по протоколу TCP с удаленным узлом, а значит нам придется выполнить "трехэтапное рукопожатие": SYN > SYN - ACK > ACK. Этот обмен данными приводит к появлению дополнительной задержки, возникающей из-за обращения данных во всех новых TCP-соединениях без исключения. В зависимости от дистанции между клиентом и сервером, а также от выбранного маршрута пакетов, эта задержка может длиться от десятков до сотен или даже тысяч миллисекунд. Все описанные действия, подразумевающие возникновение задержек, должны быть выполнены до момента передачи посредством созданного соединения хотя бы одного байта данных приложения.

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

Наконец, у Chrome появляется возможность передачи HTTP-запроса (requestStart на Рисунке 1.1). После получения запроса сервер может обработать его и отправить данные ответа назад клиенту. Эта процедура подразумевает как минимум одно обращение данных, а также затраты времени на обработку запроса на сервере. После этого отправка запроса будет завершена за исключением того случая, когда в ответе содержится перенаправление HTTP, при появлении которого нам придется повторить весь цикл отправки запроса еще раз. На ваших страницах есть несколько необоснованных перенаправлений? Возможно, вам захочется пересмотреть решение об их использовании.

Вы подсчитали все возникающие задержки? Для иллюстрации проблемы, давайте примем к рассмотрению худший сценарий работы стандартного широкополосного соединения: отсутствие данных в локальном кэше с последующим достаточно быстрым запросом к DNS-серверу (50 мс), рукопожатие TCP, установление безопасного соединения по технологии SSL и достаточно быстрый ответ сервера на запрос (100 мс) с временем обращения (RTT) в 80 мс (среднее время обращения в континентальной части США):
  • 50 мс для осуществления запроса к DNS-серверу
  • 80 мс для осуществления рукопожатия TCP (один период обращения RTT)
  • 160 мс для осуществления рукопожатия SSL (два периода обращения RTT)
  • 40 мс для отправки запроса серверу
  • 100 мс для обработки запроса сервером
  • 40 мс для принятия запроса от сервера
Получается, что на отдельный запрос тратятся 470 миллисекунд, причем более 80% этого времени тратится на задержки при передаче по сети, а не на непосредственную обработку данных сервером для выполнения запроса - здесь нам придется немного поработать. Фактически, даже задержка в 470 миллисекунд может быть достаточно оптимистичным прогнозом:
  • В том случае, если ответ сервера не умещается в начальное окно перегрузки TCP (4-15 Кб), выполняется еще одно или несколько дополнительных обращений данных с соответствующими задержками.1
  • Задержки при использовании SSL могут быть даже более длительными в том случае, если нам необходимо получить отсутствующий сертификат или выполнить проверку сертификата с использованием сети (online certificate status check - OCSC), так как для этих операций необходимо создавать новое соединение TCP, что приведет к дополнительным задержкам в сотни или даже тысячи миллисекунд.

Продолжение статьи: Что значит "достаточно быстро"?.