Почему мы не используем CDN: рассказ про SPDY и SSL

Дата публикации:Февраль 8, 2014

Повествование ведется от лица Zack Tollman из компании thethemefoundry.com.

На прошлой неделе мы перешли на SSL-протокол, который был установлен для всего нашего сайта. Мы трепетно подошли к этому моменту, но не обошлось и без некоторого волнения. Мы переживали по поводу того, как это скажется на производительности сайта. Поэтому мы решили сконцентрироваться именно на производительности в процессе перехода. Использование CDN (сети доставки контента) для нового сайта казалось интересным и удачным решением, которое, как мы предполагали, поможет нам ускорить работу сайта. Однако после небольшого тестирования различных CDN мы пришли к некоторым неожиданным результатам.

До перехода на CDN

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

prelaunch

Здесь нужно отметить несколько важных аспектов. Во-первых, время до получения первого байта (TTFB) равнялось 205ms. Значение TTFB – это время поиска DNS (84ms; выделено сине-зеленым цветом) + квитирование связи TCP (95ms; выделено оранжевым цветом) + время до получения первого ответа HTML-заголовка (26ms; выделено ярко-зеленым). Время TTFB в 205ms является вполне приемлемым, т.е. мы обслуживаем WordPress действительно быстро и нашего сетевого соединения вполне хватает. Во-вторых, весь сайт загружается за 1600ms (1.6s; синяя линия). У нас имеются некоторые дополнительные скрипты, которые включаются позже, однако они не влияют на создание страницы. В-третьих, обратите внимания на диагональный «водопад». Это прекрасная визуализация данных, загружаемых последовательно. Современные браузеры могут открывать множество соединений в одно и то же время к одному URL, однако каждое из них требует отдельного TCP-соединения. Это приводит к появлению диагонального «водопада». Наконец, обратите внимание на 6 уникальных оранжевых столбиков до 16 пункта. Эти оранжевые столбцы отражают время, которое требуется браузеру для соединения с сервером. Как вы можете видеть, времени требуется немного.

Старый сайт будет нашей отправной точкой для измерения производительности нового сайта. К сожалению, мы не можем провести сравнение 1:1 между сайтами, поскольку эти два сервера находятся в разных локациях (Нью-Джерси и Техас). Оглядываясь назад, мне действительно жаль, что эти серверы не были размещены в одной физической локации, поскольку это привело бы к получению более серьезных выводов. Несмотря на это, я считаю, что те результаты, которые мы имеем, по-прежнему будут интересны.

Почему SSL имеет проблемы с производительностью

Протокол SSL имеет присущие ему проблемы с производительностью. На самом базовом уровне SSL требует дополнительного раундтрипа (приема-передачи пакетов) между сервером и браузером. Чтобы получить пример того, как SSL влияет на производительность, достаточно взглянуть на изображение выше, где квитирование связи TCP составляет 95ms. По существу это время приема-передачи (RTT) между тестовой локацией (Лос-Анджелес) и сервером (Нью-Джерси). Согласование SSL требует совершить два дополнительных раундтрипа между сервером и браузером. Таким образом, если бы мы просто применили тщательно настроенную SSL-реализацию к нашим старым серверам, то мы бы получили двойное увеличение времени 95ms x 2 (190ms) на согласование SSL, что в итоге привело бы к увеличению TTFB на 190 ms. Кроме того, если ваш сервер не будет корректно настроен, то вы, скорее всего, столкнетесь с дополнительными издержками. В целом, при добавлении SSL важно очень тщательно рассмотреть влияние на производительность.

Готовим Nginx к SSL

Учитывая предупреждения Ilya Grigorik о 5 дополнительных раундтрипах для «ванильной» сборки Nginx, мы воспользовались ручной компиляцией Nginx (основной версии пакета). Мы использовали Nginx 1.5.9 (чтобы обойти баг с «большим сертификатом»), скомпилировали в OpenSSL 1.0.1e (для включения NPN) и включили Perfect Forward Secrecy (чтобы добавить дополнительную защиту), чтобы число дополнительных раундтрипов было не более 2 при реализации SSL для сайта. Мы добавили следующие директивы к блоку сервера для нашего сайта:

ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;

ssl_prefer_server_ciphers on;

ssl_ciphers               ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;

ssl_buffer_size           8k;

В первой строке мы объявляем TLS-версии, которые мы поддерживаем. Это позволяет сайту поддерживать широкий спектр защищенных соединений с браузерами. Единственный браузер, который не поддерживается – это IE6, что оказалось для нас вполне приемлемо. IE6 поддерживает только SSL 3.0 и ниже, который подвержен renegotiation-уязвимости. В следующей строке мы выбираем предпочтительные шифры, используемые для согласования TLS. Мы решили воспользоваться рекомендациями Hynek Schlawack, которые проверены Qualys SSL Labs. Наконец, мы уменьшаем размер SSL буфера (по умолчанию 16kb), чтобы избежать сценария переполнения буфера, который привел бы к дополнительным раундтрипам в обе стороны. Наконец, такая реализация показала себя как A в SSL Labs – прекрасном инструменте для изучения вашей реализации SSL.

В ходе настройки сервера мы также убедились в том, что реализовали SPDY в Nginx. SPDY поддерживается Nginx по умолчанию, начиная с версии 1.3.15. Ранние версии Nginx нужно вручную компилировать для поддержки SPDY. SPDY стал отправной точкой для HTTP 2.0. SPDY – это транспортный слой, реализованный над SSL и обеспечивающий HTTP-мультиплексирование, расстановку приоритетов и передачу данных по инициативе сервера. Мы надеялись на то, что если мы в результате применения SSL столкнемся с падением производительности, то мы сможем возместить затраты по времени при помощи SPDY улучшений производительности. К счастью, прямо перед тем, как мы начали это делать, вышел патч SPDY 3.1, предоставленный Automattic и MaxCDN, и мы смогли перейти к нашей реализации Nginx.

Если вы хотите получить аналогичную сборку Nginx, я рекомендую посмотреть на наши инструкции по компиляции Nginx. Эти инструкции позволяют откомпилировать Nginx с поддержкой PageSpeed и Nginx Cache Purge.

CDN для ускорения

Мы долгое время обдумывали применение CDN на нашем сайте. Мы решили сделать это вместе с вышедшим обновлением. Опять же, мы считали, что добавление улучшения скорости с помощью CDN поможет нам смягчить проблемы с производительностью, вызванные переходом к SSL. Мы получили действительно интересный опыт, связанный с изучением CDN-провайдеров, о котором мы напишем позже. Для начала мы выбрали MaxCDN, который оказалось действительно легко и быстро установить и настроить. Мы использовали плагин от Марка Джекита с несколькими изменениями для совместимости с https.

Производительность с CDN

Когда все было сделано, я решил тут же перейти к тестированию сайта.

cdn_perf

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

Первое, что нужно отметить: в нашей гонке к TTFB появился новый цвет. Фиолетовый столбец в пункте 1 отражает SSL-согласование. Мы ожидали, что оно появится. Начальное соединение, которое отражало наше время приема-передачи пакетов, стало равно 57ms, а SSL-согласование заняло 103ms. Это говорит о том, что мы успешно избежали дополнительных раундтрипов, о которых предостерегал Ilya в своей статье, и остались в районе 1-2 дополнительных раундтрипов, что вполне приемлемо. Если бы мы просто реализовали SSL, то в таком случае наша производительность стала бы хуже из-за 1-2 раундтрипов, что является ожидаемым результатом. Даже такой результат натолкнул меня на мысль, что мы добились наших целей производительности.

К сожалению, здесь присутствуют и другие строки, которые нужно рассмотреть, и они выглядят далеко не идеально. Во второй строке время согласования SSL обеспокоило нас. Эта строка отражает загрузку CSS-файла для нашего сайта с серверов MaxCDN. Данный запрос включает в себя поиск DNS (76ms; сине-зеленый цвет), TCP-соединение (110ms; оранжевый цвет) и SSL-согласование (429ms; фиолетовый). Обратите внимание, что SSL-согласование вышло примерно в 4 раза дольше, чем начальное TCP-соединение. Ясно, что SSL-согласование настроено не слишком хорошо. Мы потратили кучу времени, настраивая скорость нашего SSL-соединения, и теперь страдаем от медленного SSL-согласования на CDN. Естественно, мы ждали совсем другого результата от применения CDN.

Что еще нужно добавить по поводу производительности CDN: согласование SSL повторяется три раза (пункты 2-13, 15-16). Кроме того, мы сталкиваемся с дополнительным поиском DNS, что замедляет загрузку наших данных. К счастью, как я и предполагал, SSL-согласование использует восстановление SSL, что в итоге приводит к заметному ускорению. Наконец, обратите внимание на диагональный «водопад» элементов. Мы видим тот же самый паттерн загрузки, с которым мы сталкивались в наших начальных тестах еще до запуска сайта.

Если сеть CDN расположена дальше от сервера

Одно из преимуществ использования CDN заключается в том, что для загрузки сайта используются серверы, которые находятся ближе всего к посетителям в физическом плане, что снижает время приема-передачи. Как вы видели, время приема-передачи – очень важная составляющая. Если вы не можете сократить количество раундтрипов, то, возможно, вы можете снизить время, которое они занимают. CDN способна помочь в этом. Я решил провести тест из Австралии, чтобы увидеть, как быстро работает наш сайт – сделано это было по той причине, что наш дизайнер, Скотт, живет там, поэтому мне хотелось узнать, как сайт будет работать у него.

perf2

Опять же, мы видим значительное время SSL-согласования с нашим сайтом. Время приема-передачи находится в диапазоне 200ms, что напоминает время приема-передачи до наших серверов. Я надеялся на то, что, даже учитывая плохое начальное время соединения с нашим сайтом, CDN поможет устранить некоторые слабые стороны и передаст данные действительно быстро. Как оказалось, этого не случилось, поскольку все тормозилось медленным SSL-согласованием и последовательными соединениями.

Без CDN

Получив не самые лучшие результаты при работе с CDN, мы решили посмотреть, как все будет работать вообще без CDN.

perf3

Эти результаты поразили меня до глубины души. Мы видим прекрасное время согласования SSL. Далее, для элементов 2-15 (наших данных) вообще отсутствует SSL-согласование или время соединения. HTTP-мультиплексирование SPDY позволяет всем этим запросам использовать одно и то же TCP-соединение. Нам не нужно открывать дополнительные соединения или SSL-согласования. Все элементы на странице загружаются примерно за 900ms, что является прекрасным результатом (да, это быстрее, чем в случае со старым сайтом, но здесь и сервер расположен ближе).

Также заметьте, что диагональный поток «водопада» стал меньше. Такая форма вышла из-за того, что SPDY позволяет слать многочисленные HTTP-запросы через одно и то же TCP-соединение. Важно отметить, что в случае использования CDN мы не увидели никаких преимуществ SPDY. Отказавшись от CDN, мы тут же увидели все плюсы повторного использования TCP-соединения и SSL-согласования.

Бесспорно, SPDY несет огромную выгоду для нас. Несмотря на то, что мы теряем 70-90ms на SSL-согласовании, мы также экономим огромное время, которое тратилось раньше на открытие большого количества соединений.

Без CDN в Австралии

Предыдущие результаты оказались очень неожиданными. О такой выгоде нельзя было даже мечтать! Теперь мы должны были принять решение по поводу CDN. Да, производительность CDN не была такой уж прекрасной, однако, возможно, она поможет Скотту из Австралии быстрее работать с сайтом.

perf4

Честно говоря, я не ожидал такого результата. Я думал, что CDN будет гораздо лучше, чем SPDY в одной локации. Все наши данные загрузились через CDN чуть менее чем за 5 секунд. Аналогичное действие через SPDY заняло примерно 2.7s. Производительность без CDN смогла одержать уверенную победу над производительностью с CDN. В нашем случае вышло так, что в плане скорости преимущества SPDY заметно перевесили плюсы от CDN.

Нужно также сказать, что мы пробовали и другие CDN. К сожалению, мы столкнулись с аналогичными результатами. Мы нашли CDN с лучшим временем SSL-согласования и свели общее время загрузки сайта из Австралии до 4.5s, однако мультиплексирование все равно сработало лучше, чем размещение данных в более близкой физической локации.

Пояснения

Чтобы внести ясность в статью, я хочу сделать некоторые пояснения. В частности:

  • Физические локации нашего старого и нового сервера отличались. Не все тесты проходили на том же самом аппаратном обеспечении, хотя оно было сопоставимо между собой.
  • Все тесты проводились в Chrome, который является самым продвинутым в плане производительности браузером. Примерно 50% наших посетителей используют Chrome, что заметно облегчило нам принятие решения.
  • Мы не рассматривали разнообразные локации по всему миру. Мы сконцентрировались на США и Австралии.
  • Мы тестировали только домашнюю страницу; однако другие страницы могут содержать в себе больше изображений и данных.

Заключение

В то время как финальное решение для нас заключалось в отказе от CDN, ваше решение может кардинально отличаться. Для нашего сайта мы столкнулись с огромной выгодой от HTTP-мультиплексирования. Данные были переданы очень быстро, мы избежали лишних соединений, а также получили выгоду от быстрых SSL-согласований. Скорость – лишь одно из преимуществ CDN. В нашем случае скорость была единственной целью, которой мы хотели добиться от CDN, но у нас это не вышло.

Оглядываясь назад, можно сказать, что использование SPDY и CDN было достаточно глупым решением. Передавая данные на другой домен, мы действительно теряем все плюсы SPDY. Изначально я не понимал, какую именно пользу может принести нам SPDY, и лишь после практического применения увидел ее. Было трудно найти CDN-провайдера, использующего SPDY. Если вы сможете объединить преимущества  SPDY и CDN, то это будет достаточно интересным действием. В теории такое возможно, если провайдер CDN поддерживает SPDY и разрешает SSL для CNAME.

Если вы являетесь разработчиков или системным администратором, то вам очень важно измерить все данные, после чего уже принять решения на базе полученных измерений. Если бы мы не протестировали производительность CDN, то мы бы по-прежнему использовали бы ее, считая, что это позволяет нам поднять производительность, не говоря уже о том, что мы бы платили за сервис, который не приносил бы нам ожидаемой пользы. Мы рады тому, что наши инвестиции в Nginx и SPDY окупились должным образом!

Источник: thethemefoundry.com/blog

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *