Илья Григорик о внедрении HTTP/2

    Известный специалист по серверной и клиентской оптимизации, соавтор WebRTC, автор книги "High Perfomance Browser Networking" Илья Григорик из Google опубликовал презентацию “HTTP/2 all the things!”, в которой объясняет, как следует настраивать серверную часть под HTTP 2.0, чтобы повысить скорость загрузки страниц и уменьшить latency, по сравнению с HTTP 1.1.


    Режим Connection View в браузере показывает загрузку элементов заглавной страницы Yahoo.com в HTTP 1.1

    Илья начинает с того, что для современных сайтов бóльшая часть задержек приходится на ожидание загрузки ресурсов, при этом полоса пропускания не является ограничивающим фактором (синим цветом на диаграмме Connection View). По статистике, для загрузки средней веб-страницы браузер делает 78 запросов к 12 различным хостам (общий размер загружаемых файлов 1232 КБ).

    Для 1 млн крупнейших сайтов интернета, по версии Alexa, на 5-мегабитном канале, среднее время загрузки страницы составляет 2,413 с, при этом CPU работает лишь 0,735 с, а остальное приходится на ожидание поступления ресурсов из сети (latency).

    Проблемы HTTP 1.1 заключаются в большом количестве запросов, ограниченном параллелизме, не работающей на практике конвейерной обработке запросов, наличии конкурентных TCP-потоков, оверхеде служебного трафика.

    Ещё одна проблема в том, что веб-мастеры перебарщивают с доменным шардингом. Они добавляют слишком много шардов, чтобы обойти ограничение браузера на 6 одновременных соединений с одним сервером, и из-за этого вредят сами себе. Трафик многократно дублируется, возникают заторы, повторные передачи и т.д.

    Проблемы с большим количеством запросов при разработке приложений под HTTP 1.1 тоже решаются неправильным образом: через concat (создание больших монолитных фрагментов кода, дорогая инвалидация кеша, отложенное исполнение JSS/CSS) и inline (дублирование ресурсов на каждой странице, сломанная приоритизация).

    Что делать?

    Всё очень просто. Новый HTTP 2.0 исправляет многие недостатки HTTP 1.1, уверен Илья Григорик. HTTP 2.0 не требует установления множества соединений и уменьшает latency при сохранении привычной семантики HTTP 1.1.



    Во-первых, все потоки смешиваются путём разбиения на фреймы (HEADERS, DATA, проч.), которые пересылаются по единственному TCP-соединению. Для фреймов действует приоритет и контроль потока. А server-push заменяет inline. Ну и, конечно, эффективное сжатие заголовков, вплоть до того, что HEADER «сжимается» до 9 байт (передаются только изменения).



    Как конкретно использовать преимущества HTTP 2.0 для оптимизации серверных приложений? Это самая интересная часть презентации Ильи Григорика.

    Устраняем доменный шардинг


    Шардинг конкретно бьёт по производительности HTTP/2, ломает приоритизацию фреймов, контроль потока и проч.

    В случае необходимости можно реализовать шардинг через altName. Если используется один IP и один сертификат, то HTTP/2 сможет открыть единственное соединение для всех шардов.

    Избавляемся от ненужных оптимизаций (concat, CSS-спрайты)


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

    Внедряем server-push вместо inline


    Сервер теперь может выдавать несколько ответов на один запрос. Клиент заказывает что-то одно, а сервер ему может дать в придачу и что-то другое. Каждый ресурс кешируется независимо (при этом необязательно кэшировать на каждый запрос, есть smart push). Кстати, с помощью серверного push-уведомления можно и аннулировать запись в клиентском кеше!

    Smart push — вообще отличная вещь. Сервер сам анализирует трафик и строит зависимости, какие ресурсы запрашивает клиент, в зависимости от referrer’а. Например, index.html → {style.css, app.js}. В соответствии с этими закономерностями и создаются правила для дальнейших push-уведомлений новым клиентам.



    Илья Григорик подчёркивает, что в случае с HTTP/2 серверы обязательно должны быть правильно сконфигурированы. Это не было так критично во времена HTTP/1.1, но теперь так оно и есть. Например, в HTTP/1.1 браузер сам высылал сначала важные запросы (index.html, style.css), придерживая второстепенные (hero.jpg, other.jpg, more.jpg и проч.), теперь же нет. Так что если не сконфигурировать сервер на обработку важных запросов в первую очередь, то пострадает производительность.

    Далее, HTTP/2 позволяет тонко контролировать поток. Например, можно сначала отправить первые несколько килобайт изображения (чтобы браузер декодировал заголовок и определил размеры картинки), потом важные скрипты, а затем уже остальную часть изображения.

    Тестирование показало, что при использовании SPDY задержка (latency) и скорость загрузки страницы уменьшаются на 30-40%.

    Например, Twitter протестировал задержку доступа к API в декабре 2013-го. Результаты в миллисекундах показаны на графике для 50-й, 75-й, 95-й и 99-й перцентили (по медиане). Интересно, что SPDY приносит больше пользы, когда клиент подключен по худшему каналу связи (low latency locale).





    Компания Google публиковала свою статистику по увеличению скорости загрузки страниц ещё год назад.


    Google News
    Google Sites
    Google Drive
    Google Maps
    По медиане
    -43%
    -27%
    -23%
    -24%
    5-я перцентиль
    (быстрые соединения)
    -32%
    -30%
    -15%
    -20%
    95-я перцентиль
    (медленные соединения)
    -44%
    -33%
    -36%
    -28%
    Встроенная поддержка HTTP/2 появится в ближайшей стабильной версии Chrome 39 и в ближайшем стабильной версии Firefox 34, так что всего через несколько месяцев большинство браузеров в интернете будут поддерживать HTTP/2 и смогут пользоваться преимуществами нового протокола (поскольку SPDY стал частью HTTP/2, то теперь его отдельная инкарнация выводится из обращения).

    На Github ведётся список известных реализаций HTTP/2 на C#, NodeJS, C++, Perl и т.д. Туда входит и библиотека nghttp2 на C. В общем, Илья Григорик призывает всех оптимизировать свои серверы под HTTP/2 и проверить корректную работу TLS.
    Support the author
    Share post

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 27

      +2
      У нас порядка 1300 JS файлов. При их пофайловом включении в страницу они грузятся 10 секунд. И затык именно на стороне браузера, который плохо работает с большим числом файлов.
        +2
        Вы ведь знаете, что можно это всё до одного файла сжать?
          +4
          Илья говорит, что не надо так делать.
            0
            При использовании HTTP2 конечно. Но я правильно понимаю что для каждого файла будет добавлено по одному фрейму для заголовков? Вроде и не много, но зачем?
              0
              Или речь о server-push?
                +9
                Ну он же объясняет почему: при изменении одного файла не надо будет загружать здоровеный «сжатый» файл.

                Для каждого файла будет 2 фрейма. Суть сферического HTTP/2 в том, что его ВНЕЗАПНО все используют и правильно выставляют приоритете ресурсам, и все сервера ВНЕЗАПНО умеют учитывать эти приоритеты и все это божественно мультиплексируются.

                Реальность такова:
                — никто еще не умеет приоритетами пользоваться (они тупо игнорируются)
                — Сервер теперт внезапно стал сложным, ему теперь состояние надо хранить
                — Мультиплексирование происходит на уровне который собственно сам является реализацией мальтиплексирования

                В результате HTTP/2 это костыли чтобы избежать TCP Slow start. Диванный аналитик во мне говорит, что лучше бы они SCTP приняли для этой цели (в мэйлингах это обсуждали)
                  0
                  У SCTP проблема с натами: многие SOHO роутеры не умеют его натить (будет по сути одно соединение на роутер), но это пол беды, ибо его так-же не умеют натить многие Large Scale NATы у ISP, а вот это существенно хуже (тут получится одно соединение на один внешний IP адрес).
                  Есть вариант SCTP over UDP, но внедрять его на несколько лет переходного периода не целесообразно.
                  Думаю что логичнее было-бы чуть-чуть потерпеть, и, лучше, посодействовать распространению IPv6. А когда он будет работать массово — можно смело использовать SCTP.
                    +1
                    Я все это понимаю, я внедрения SCTP жду с тех пор как он в ядро FreeBSD попал.
                      0
                      В FreeBSD есть, в линуксе тоже. А вот, в Mac OS я его как-то я не наблюдаю (на 10.10 я еще не обновлялся, может там будет...). В виндовсе, насколько я понимаю, встроенного тоже нет (но есть сторонний).
                      При таком раскладе ни о каком массовом внедрении пока речи, к сожалению, нет :(
          –5
          А зачем слеш? Ещё один слеш? Мало слешей в http? :D С третьей минуты blip.tv/beettv/tim-berners-lee-looks-back-the-in-web-addresses-was-unnecessary-2727797
            +6
            Это версия, в uri она не указывается. Сейчас вы используете HTTP/1.1
              –1
              То, что в машинных беседах пробел используется в качестве разделителя между протоколом и кодом ответа (что и вынуждает использовать слеш для указания версии, ибо иначе версия будет ошибочно считаться кодом ответа), не значит что нам — человекам — стоит поступать точно так же. Пробел вполне себе неплохой символ. Но, видимо, недостаточно модный.
            +1
            Круто, но судя по скринам, HTTP/2 идет к statefull.
              +2
              Это всё здорово, я сам в восторге от всего этого, но есть определённые вопросы и проблемы:

              1) Никто не предоставил воспроизводимого тестирования. При реальном тестировании такие крутые результаты не воспроизводятся. Вообще непонятно, как проводилось тестирование и что считают под «скоростью загрузки». Есть подозрение, что считают время установления соединений, а ведь на скорость показа страницы влияет ещё куча факторов.

              2) Nginx тупо не умеет Server push. Большая часть прелестей испаряется. Не говоря уж о тонком контроле потока. Подозреваю, что на реализацию всего этого нужен не один год.

              3) HTTP всё ещё базируется на TCP, а это значит, как признаёт сам Илья, что никто не отменял блокировку потока на уровне протокола TCP: потерялся один пакет — всё, что после него, не может быть обработано из-за гарантированной очередности пакетов, нивелируя «потоки» в HTTP/2, что опять-таки актуально на медленных и нестабильных каналах.
              Да, Гугл делает QUIC, но в экспериментальном порядке, только в Хромиуме. Спецификации нет, единственный актуальный источник информации — исходный код Хромиума.

              4) Многопоточная загрузка по отдельным ресурсам не исключает «мерцания» от того, что картинки показываются по мере загрузки. Мерцание больше трёх кадров в секунду вредно с точки зрения доступности. Спрайты не перестают быть актуальными. А когда всё уже склеивается, как рекомендуется для HTTP/1.1, преимущества HTTP/2 опять же нивелируются. Тот же вопрос про тесты.
                0
                Возможно такие цифры даёт тестирование 10% пользователей Гугла.
                Т.с. эффект от масштаба, а в скромных ДЦ и цифры будут скромнее.

                Я давно наблюдаю за развитием SPDY и потом HTTP2, но для простого обывателя пока не вижу ни чего, что могло бы как-то улучшить работу сайта с котятками.
                  0
                  У меня, собственно, тот же вопрос: в чем кардинальное улучшение HTTP/2.0 по сравнению с имеющимися технологиями объединения файлов? И можно качать хоть в 10 потоков с сервера: на канал это кардинально не повлияет. Да на 10-25% он будет лучше утилизироваться, но браузеры и так уже его утилизируют по полной, когда это возможно.
                    0
                    На скринах же видео, что у TCP очень много времени уходит на установку сессии.

                    А так же: en.wikipedia.org/wiki/Slow-start
                      0
                      Подождите. TCP Slow Start уже сейчас можно через пересборку nginx сделать, для этого HTTP/2.0 не нужен (Илья же и объясняет в своих статьях, как именно). И keepalive/SPDY сейчас решает проблему сессий (не решает проблему пинга, но на больших объемах и небольшом количестве файлов она вообще не существенна).
                      Другое дело, что с объединением/распараллеливанием файлов никто толком работать не хочет, поэтому нужен HTTP/2.0 «из коробки». Но у него и минусов в текущей формулировке хватает (взять те же блокирующие ресурсы в общем потоке).
                        0
                        > взять те же блокирующие ресурсы в общем потоке
                        Так они же должны приоритизироваться по идее.
                          0
                          Вы не путаете с TLS TTFB? Потому, что проблемы TCP Slow Start решаются обычно сетевым стэком ОС. Есть часовой доклад этого же Ильи в каких версиях линукса увеличили стартовое окно. Так, что долгая TCP сессия нужна, чтобы окно было оптимальным.

                          Одно дело качать 16 гигабайтный файл по http, да, там просто открыл пачку потоков и качаешь. Другое дело, когда браузеру надо открыть 30 соеденений, чтобы скачать два мегабайта. Сжатие заголовков опять же не плохое нововедение и то, что протокол наконец-то стал бинарным.
                            0
                            там 2 slow start, и Илья об обоих говорил. Правда, нам бы еще определиться, что называть Slow Start… :)
                              0
                              Есть TCP Slow Start это решается только на уровне ядра ОС. И у этого есть вполне внятное определение: TCP использует очень маленькое окно на свежих сессия, чтобы случайно не забить канал и постепенно увеличивает его до тех пор пока не становиться хуже — если стало хуже то уменьшает.

                              Есть так же TLS Time To First Byte, он уже решается реализацией и на уровне приложения: False Start, правильном хранении TLS сессий, и прочими ухищрениями. TLS TTFB же это целый набор болячек. Илья правда говорит, что повсеместное внедрение TLS ускорит сам TLS — я слабо представляю как связано между собой.
                                0
                                Initial Congestion Window ускоряется на уровне настроек, это доступно для любого сервера. icwnd = 10
                                  0
                                  Я лишь повторяю слова Ильи.
                                    0
                                    Но к моему первоначальному вопросу эти слова никак не относятся. Повторюсь: как HTTP/2.0 кардинально улучшит текущую ситуацию со скоростью сайтов? Если никак, то зачем вокруг него столько шума?
                                    HTML 5 ввел в обращение новую семантику и медиа-форматы и позволил разрабатывать сайты проще. Это был прорыв. Где в случае HTTP/2.0 прорыв?
                                      0
                                      Нет никакого прорыва, это надо назвать HTTP/1.2.

                                      Два больших изменения это:
                                      — Бинарный, а не текстовый
                                      — Мультиплексинг
                                      — Ну сжатие заголовоком можно добавить, но не думаю, что принуждение сервера быть stateful это плюс.

                                      Промизы тоже ускорят, клиент вероятно уже будет иметь файл до того как он узнает, что файл нужен. Ненужность сжатия позволит правильно использовать кэш, а не менять весь спрайтшит из-за одной иконки или еще хуже раздутый css файл из-за datauri.

                                      Насколько я знаю, Initial Congestion Window, таки выставляется ядром на весь интерфейс. В «свежих» ядрах просто увеличили дефолтное значение.
                    +4
                    Вопрос пользы от кеширования статики в браузере весьма тонкий: сейчас на (почти) любом сайте так много статики, что несколько сайтов довольно сильно могут забить кеш браузеру. У иных браузеров кеш небольшой (все мобильные, как вариант). Далее вопрос: какое количество данных в кеше браузера еще ускоряет его работу, а какое — даже и замедлит? Тем более что висит еще на новый сайт выдавливает старое из кеша.

                    Я бы сказал, что задать кеш в жуткую величину в 1 Гб не спасет, а усугубит проблему: файлы лягут на диск, они не будут в горячем кеше ФС, и их доставать с диска может оказаться не сильно дешевле, чем взять с сайта.

                    Далеко не надо ходить за примером: главная Хабра весит 3.6 Мб (точнее, столько браузер у меня принял по сети), их них только пара десятков килобайтов — сам html. Прикинем то же без сжатия, и получаем, что в кеше бы забили статикой мегабайтов 10. Но веб Хабр — не один (и даже не основной для многих) сайт, который каждый из нас посещает за сутки, так что суммарный суточный прирост кеша будет явно в сотни метров. iPad такое не выдержит, браузеры на ПК — когда как.

                    Я к тому, что склеить все css в единый файл в файловой системе веб-сервера — тупо все равно быстрее и надежнее, чем отправить в браузер 100 маленьких css-ок, выставив каждой время жизни в кеше в 5 лет. Потому что не доживут ни общий файл, ни 100 мелких до этих лет, выдавит их поток более свежей статики. А вот скорость загрузки одного файла даже по http 1.1 со сжатием будет вполне нормальной, и http 2 с его наворотами сильно не спасет ситуацию. То же и с js.

                    Only users with full accounts can post comments. Log in, please.