Eternal static (RIT 2011)
Upcoming SlideShare
Loading in...5
×
 

Eternal static (RIT 2011)

on

  • 650 views

«Вечная статика» оптимизация отдачи контента

«Вечная статика» оптимизация отдачи контента

Statistics

Views

Total Views
650
Slideshare-icon Views on SlideShare
621
Embed Views
29

Actions

Likes
2
Downloads
4
Comments
0

1 Embed 29

http://protey.ru 29

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Eternal static (RIT 2011) Eternal static (RIT 2011) Presentation Transcript

    • «Вечная статика»оптимизация отдачи контента
      Сергей Скворцов
      2011-04-26
    • I. Теория
      3
    • Стороны и связь
      Браузер
      отображение/рендеринг страниц/данных
      Протокол
      передача данных: запрос-ответ или stream
      Сервер
      приём запросов, формирование и передача ответов
    • Скорость показа контента
      Скорость отображения в браузере
      Скорость передачи по сети
      Скорость ответа от сервера
    • 1)Скорость отображения в браузере
      Рендеринг / вёрстка
      Встраивание ресурсов/данных
      Data URI, CSS sprites
      увеличивает размер ответа
      AJAX, WebSockets
      Отложенная загрузка;Prefetching
      JavaScript: async/defer; post-load
    • 1.1) Рендеринг/вёрстка
      Корректный порядок указания ресурсов (JS/CSS)
      Yahoo «Best Practices for Speeding Up Your Web Site»
      Самоограничения: CSSexpressions
      Прогрессивная вёрстка
      см. StoyanStefanov (Yahoo)
      Верстка независимыми блоками
      см. Виталий Харисов (Яндекс)
      Шаблоны на client-side (XSLT)
    • 2)Скорость передачи по сети
      Каналы…
      … связность, распределение по странам, ДЦ
      DNS-resolving
      Уменьшение числа lookup’ов (число хостов, TTL)
      Geo-balancing, IP anycast
      Постоянные соединения
      HTTP 1.0 keep-alive == HTTP 1.1 persistent
    • 2)Скорость передачи по сети
      Раздача с нескольких хостов
      CDN; DNS/geo-balancing, TCP anycast
      Параллелизация загрузки: default лимит у браузеров – не более 6 запросов на хост
      JS-хостинги (для jQuery, YUI, …)
      13% страниц используют Google Libraries API
      Хорошо кэшируютсямежду сайтами
      Privacy: источник Referer’ов для поисковиков
    • 2)Скорость передачи по сети
      HTTP pipelining - не популярен
      Дружим с proxy-servers, и ненавидим их
      Кэширование!
      Их 10% запросов (оценка по Openstat.Trends)
      «Над»-протоколы (HTTPS, SPDY)
      HTTPS – безопасность, но overhead
      SPDY – только Google, нет поддержки в nginx :)
    • 3)Скорость ответа от сервера
      Скорость генерации ответа
      Уменьшение размера ответа
      Уменьшение размера запроса
      Уменьшение числа запросов
    • 3.1) Скорость генерации ответа
      Хорошие frontend’ы
      Быстрые серверы приложений (backend’ы)
      Прогрессивная отдача контента
      flush()
      Кэширование:
      данных (memcached)
      ответа (mod_cache*)
    • 3.2) Уменьшение размера ответа
      Сжатие ответа
      ngx_http_gzip, ngx_http_gzip_static
      mod_gzip, mod_deflate
      Отложенная «подгрузка» JS, контента
      Post-loading
    • 3.2) Уменьшение размера ответа
      Оптимизация содержимого (minification)
      Оптимизация JS/CSS
      Closurecompiler, YUI Compressor
      Оптимизация графики
      Оптимизация HTML
      Пробелы, комментарии, default атрибуты, …
      htmlcompressor,или при компиляции шаблонов 
    • 3.3) Уменьшение размера запроса
      Отдача статики в другом домене
      Чтобы не слать лишние заголовки: Cookie
      Уменьшаем размер Cookie
      FYI: максимальный суммарный размер на домен:
      Firefox, Chrome - no limit
      Opera, IE6 - 4096байт
      IE8 - 10234байт
    • 3.4) Уменьшение числа запросов
      Кэширование контента на стороне браузера
      Объединение стилей и скриптов (JS, CSS)
      Объединение и внедрение картинок(CSS sprites, Data URI, MHTML)
      ценой большего размера ответа
      Избегать редиректов
    • Итого
      Всё вышеописанное можно использовать как checklist, варианты ответов:
      Уже так делаем
      Не делаем, потому что (программисты|админы) сказали что…
      Не знали / совсем забыли – надо подумать
    • II. Приём
      18
    • Как работает кэширование в HTTP
      При первом запросе к ресурсу браузер:
      Запоминает заголовки ответаLast-Modified и/ли ETag
      Определяет сколько времени можно не обращаться к серверу, а использовать локальный кэш - на основе данных из заголовков:
      Expires
      Cache-Control
      http://www.w3.org/Protocols/HTTP/1.1/rfc2616bis/
    • Как работает кэширование в HTTP
      При втором запросе к серверу:
      Если ресурс в локальном кэше – браузер делает валидацию – шлёт условный запрос:
      If-Unmodified-Sinceи/ли If-None-Match
      Если ресурс не менялся (304 Not modified):ждём опять expiration
    • Нюансы де-факто
      По факту ETagиспользуетсядля статики так:
      nginx: не вычисляет вообще
      Apache:inode-size-timestamp
      IIS:Filetimestamp:ChangeNumber
      Это не работает на кластере машин
      inodeи ChangeNumberбудут разные
    • Проблемы этого дня
      Заголовки ExpiresиCache-Control: max-age тупо не выставляют
      56% запросов вообще не указывают expiration
      24% запросов может кэшироваться http://www.stevesouders.com/blog/2011/04/18/http-archive-max-ag/
      Нопри этом есть статика – которая меняется редко:
      CSS, JavaScript, картинки, Flash, иконки (!)
    • Проблемы этого дня
      Поскольку нет expiration – каждый раз шлётся запрос (в надежде на 304 Not modified)
      Но такой запрос это:
      Минимум 2 IP пакета
      Время на ожидание ответа
      Особенно печально ждать когда блокируемся на рендеринге
    • Решение: выставлять expiration
      Выставлять expiration для динамики несложно (семантику знает backend)
      Но любой константный expiration для статики приводит к проблемам при обновлении сайта (новый дизайн, шаблоны, …)
      Единый глобальный Expire - выставить нельзя
      Выход: версионированиена уровне URI
    • Версионирование
      Наивный подход – добавлять «?» + timestamp: /favicon.ico?ver=3
      Многие прокси серверы считают URL с «?» некэшируемым в принципе
      Не учитываются зависимости внутри ресурса:
      /style.css?ver=3ссылается внутри на /logo.png?ver=5
    • Версионирование: верный подход
      Добавляем версию внутрь пути: /favicon_1303591683.ico
      Версию можно брать из VCS, но не каждый ресурс лежит в репозитории, он может создаваться при выкатке
      Очевидный вариант – timestamp
      Для файлов с зависимостями «наружу» – считаем версию с учётом зависимостей, пример:
      md5( timestamp + @versioned_dependencies_urls)
      Экономим байты – используя Base64 URLSafe
    • Обработка внешних зависимостей
      Делаем общий префикс /s/в URLах статики
      Для всех шаблонов, которые ссылаются на версионированную статику, обновляем ссылки
      Всё! Статика стала вечной, поэтому:
      location /s/ {
      expires max;
      gzip_static on;
      }
    • Применимость
      • Стоит применять для:
      Файлов стилей и скриптов (CSS, JS)
      Картинок, являющихся частью дизайна/шаблона
      Flash-объектов
      • Не надо применять для:
      Скачиваемых файлов (и подлежащих индексации)
      Особо актуально:
      Мобильные сайты
    • Немного статистики:число запросов
    • mime-types:по числу запросов
    • mime-types:медиана размера ответа
    • HTTP Archive:медиана размера ответа
      http://httparchive.org/interesting.php#responsesizes
    • 33
      III. Практика
    • Htdocs layout
      На файловой системе:
      htdocs/
      frontend/
      eternal/
      backend/
      • frontend - статика, отдаётся nginx
      • eternal– «вечная» статика, отдаётся nginx
      • backend - шаблоны, используются в upstream
    • VCS layout
      В репозитории:
      trunk/
      htdocs-frontend/
      a/
      css/
      img/
      js/
      htdocs-backend/
    • Сборка пакетов: шаги
      Checkout
      Processing
      Стадия «generate»
      Стадия «preprocess»
      Стадия «optimize»
      Стадия «produce»
      Генерация «вечной статики» (кладём в /s/)
      Packing distfiles
    • Сборка пакетов – Processing
      Стадия «generate»
      Генерация новых файлов, на основе checkout’а
      img2css– набор иконок в один CSS файл
      Стадия «preprocess»
      Изменение содержимого файла, и/ли метаданных о нём
      inline-includes– объединение файлов
      CSS: раскрытие @import
      JavaScript: раскрытие _include_js()
    • Сборка пакетов – Processing
      Стадия «optimize»
      Оптимизация формата файла, с сохранением инварианта его семантики
      yuicompressor– JS/CSS minification
      Стадия «produce»
      Генерация других файлов на основе итоговых
      gzip_static– создание сжатой версии статики
    • Сборка пакетов – «вечная» статика
      Конфигурация:
      <handler
      name="eternal-static"
      process_path="/a/"
      target_path="/s/"
      match_ext="gif icojpg pngswfjscss"
      expand_ext="jscss"
      />
    • Сборка пакетов – «вечная» статика
      Сканируем директорию process_pathна предмет статических файлов с нужными расширениями
      Обрабатываем раскрываемые файлы (*.js *.css) на предмет ссылок на другие найденные ранее статические файлы
      Строим граф зависимостей
    • Сборка пакетов – «вечная» статика
      В директории target_pathсоздаём соотв. версии статических файлов (и их gzipped-версий, если у файлов был handlergzip_static)
      Итоговый файл будет называтьсяfilename_revision.ext, где revision – ревизия файла
      /a/file.txt /s/file_REVISION.txt
    • Сборка пакетов – «вечная» статика
      Для статического файла, который не имеет зависимостей (в т.ч. тех, которые не раскрываются вообще, типа картинок), ревизия равна mtime
      VCS ревизия может быть недоступна, если файл генерировался.
      При генерации файлов mtimeфинального файла всегда равен максимальному mtimeего исходных файлов
    • Сборка пакетов – «вечная» статика
      Для статического файла, который имеет зависимости, ревизия вычисляется как md5( join('0', mtime, sort@eternal_static_deps) ) - т.е. создаётся семантически уникальная ревизия файла.
      Жёсткое создание ревизии (md5 от тела файла) не используется, чтобы при изменениях контента, которые семантически инвариантны (например, применён новый алгоритм оптимизации/obfuscation файлов) не создавалась новая ревизия.
    • Сборка пакетов – «вечная» статика
      Создаём файл /s/.mapping, который содержит строки с парами "статический файл", "вечно-статический файл":
      /a/js/base.js /s/js/base_iv6uTQ.js
      /s/css/main.css /s/css/main_msy5mT8H-Ak6hBAsce-30w.css
    • Пример: www.openstat.ru
      <!DOCTYPE HTML><html lang="ru"><head>
      <title>Интернет-статистика и веб-аналитика | Openstat: Независимая аналитика</title>
      <link rel="stylesheet" type="text/css" href="/s/css/main_msy5mT8H-Ak6hBAsce-30w.css" />
      <script type="text/javascript" src="/s/js/base_iv6uTQ.js"></script>
    • Установка пакетов
      Файлы ставятся в share/htdocs/frontend
      На этапе POST-INSTALL запускаем:
      rsync -rlptgoD--checksum--delete-after
      share/htdocs/frontend
      htdocs/frontend
      Это делается для того, чтобы при удалении пакета в htdocs/frontendчто-то оставалось
    • Установка пакетов
      Также копируем вечную статику:
      rsync -rlptgoD--checksum
      htdocs/frontend/s/
      htdocs/eternal
      В htdocs/eternalфайлы никогда не удаляются!
    • Установка пакетов
      Раскрываем(и атомарно замещаем) файлы шаблонов по списку из /s/.mapping:htdocs/backend
      Поскольку директория /a/также ставится, то задержка в раскрытии файлов, равно как их нераскрытиене влияет фатально на работу сайта - просто запросы пойдут к "менее вечной" статике.
    • Конфигурация frontend’а
      Пример для обычного веб-сервера:
      location ^~ /s/ {
      alias htdocs/eternal;
      gzip_static on;
      expires max;
      }
    • Соглашения
      Соглашения для раскрываемых файлов:
      Полное указание пути на ссылаемые файлы
      В JS не использовать составление URLиз частей , прописывать в коде полностью(как hash)
    • favicon
      • IE(и иные браузеры) всегда запрашивают /favicon.ico, если нет<link rel=”icon” …/>
      Выдавать 404 – не выход, поскольку запросы всё равно будут идти
      Правильно так:
      location = /favicon.ico {
      root /path/to/htdocs;
      expires 30d;
      }
    • IV. Tips & tricks
      52
    • Битва за байты: заголовки
      Заголовок Server:
      Вообще-то его надо оставлять – это полезная статистика
      https://www.openstat.ru/counter/trends/
      Но надо убирать из него длинных список скомпилированных модулей:
      Server: Apache/1.3.27 (Unix) mru_xml/0.471 gorgona/2.1 mod_jk/1.2.4 mod_ruby/1.0.7 Ruby/1.6.8 mod_mrim/0.17
      Также убирать прочие «гордые» заголовки:
      X-Powered-By: PHP/5.2.6-1+lenny9
    • Битва за байты: HTML5 vs. XHTML
    • Используем TLS/SSL
      TLS/SSL – уже не дорого в плане вычислений (CPU)
      Отдельные аппаратные акселераторы уже не нужны
      CPU Intel Core i5+ поддерживают AES instruction set
      Privacy & confidentiality – всегда популярно среди параноиков
      https://gmail.com, https://encrypted.google.com
      Цена сертификата Thawte - всего $45
    • Минусы TLS/SSL
      Дополнительные 4+ IP пакета на handshake (размер public key имеет значение!)
      Больший размер ответов
      record header, padding (если block cipher)
      При тщательно подобранном размере ответа ресурса (чтобы, скажем, влез в 1 IP пакет),применение SSL может повлечь +1 IP пакет
    • Минусы TLS/SSL
      Блокирование на OCSP (проверка сертификата сервера) = +N*100ms
      FF3+; IE* on Vista / Win7, …
      Решение - OCSP stapling
      Не работает с chained certs
      +~1KB данных (OCSP ответ)
      Есть в Apache, нет в nginx
    • Минусы TLS/SSL
      SSL + IE6/7+data:uriв HTML =«небезопасный ресурс»
      Доля IE6 + IE7 в Рунете - 9%
      SSL + отдача статики параллельно с нескольких хостов= дополнительные затраты на сертификаты
      либо несколько сертификатов для разных хостов (www.foobar.ru, img.foobar.ru)
      либо условно дорогой wildcard(*.foobar.ru)
    • Вопросы?(по теме доклада)
      http://protey.ru/blog/2011/04/rit-2011.html
      Сергей Скворцов
      skv@protey.ru
      59