Перед тем как принять решение о работе с той или иной CDN хотелось бы убедиться, что она будет делать именно то, что мы от нее ожидаем. Конечно, вы прочитали документацию, и все подробно обсудили с консультантами, но ведь этого мало? И если вы подходите к делу так же въедливо, как и мы, этого недостаточно. Вы бы хотели протестировать CDN, получить объективные характеристики ее работы, сравнить их со своими требованиями и т. п.

Dummy Origin – это тот инструмент, который позволяет сделать все это наилучшим образом, а главное – легко.

Dummy Origin – специализированный сервер, написанный на языке Go. Он был разработан специально для тестирования CDN, работающих в режиме pull. Он легкий, быстрый, его легко установить, и самое главное – он с открытым кодом, т. е. бесплатный!

Зачем же использовать Dummy Origin, а не протестировать CDN прямо с использованием вашего рабочего сервера? Потому что так проще проверить различные режимы работы прокси.

  • Вам не надо ничего менять в конфигурации, настройках сервера и сайтов.
  • Можно свободно менять заголовки в ответах и анализировать, как CDN на это реагирует.
  • Очень легко протестировать разные критические сценарии типа «мой сервер выдает 502 ошибку, поддерживает ли CDN раздачу устаревших копий страниц во время оффлайна основного сайта?

Возможности Dummy Origin


Основное: Dummy Origin осуществляет инъекцию произвольных заголовков в запрос. Делается это при помощи строки параметров URL, которая потом вставляются как заголовок запроса. Например, посылаете в URL ?ETag="41a0544696e19971383984fdaaeb5aed", Dummy Origin выдаст ETag:"41a0544696e19971383984fdaaeb5aed" в заголовке запроса.

Этот механизм позволяет тестировать поведение CDN без изменения конфигурации сервера и его перезагрузки, что потребовалось бы для изменения заголовков.

Другие возможности Dummy Origin:
Возможность Описание Преимущества
Gzip Сжимает ответ с помощью стандартной Gzip компрессии. Основывается на расширениях файлов, а не на Content-Type. В настоящее время поддерживает .html, .css .js и .json расширения, но остальные можно легко добавить Тестирует работу CDN со сжатыми файлами
Условные запросы Обычно сервер выдает Last-Modified заголовок вместе с ответом 200 и выдает 304 или 200 если получает If-Modified-Since запрос Позволяет проверить, отправляет ли CDN запросы с условием после истечения срока годности файла в кэше
Запросы диапазонов Отправляет запрошенный диапазон байтов в 206 частичном ответе и соответствующий заголовок Content-Length Важно для пересылки больших объемов данных через CDN, например, видеофайлов
404 и 301 Отдает ошибку 404, если ресурс не существует, делает 301-редирект, если запрошен /index.html Кэширует ли CDN 404 ответы? Передает ли CDN 301 дальше или же она обрабатывает редирект сама?
Специальный генератор ошибок Когда сервер получает запрос в виде GET /err/<code>, он возвращает http статус <code>. Величина <code> должна быть в диапазоне от 400 до 599 Позволяет тестировать поведение CDN в случае выдачи сервером различных ошибок. В частности, можно проверить, кэширует ли CDN ответ 404.
X-Tb-Time Сервер всегда выдает текущее время в заголовке X-Tb-Time Помогает определить, обслуживает ли CDN запрос данными из кэша или от сервера и как долго содержимое находится уже в кэше
Поддержка Loggly Детали запроса и ответа обрабатываются через Loggly, если определена переменная окружения LOGGLY_TOKEN Loggly — облачный сервис обработки логов, очень удобный для разбора логов запросов CDN к серверу

В Dummy Origin на сегодняшний день нет:

  • HTTPS
  • Brotli (алгоритм сжатия, применяемый в частности в браузере Chrome)
  • Не может выдавать различное содержимое/заголовки на основе запросов с заголовками User-Agent или Accept-Language.

Установка и конфигурирование


Установка сервера описана в README.md на GitHub

Разместите несколько файлов на сервере. Они должны быть аналогичны тем файлам, которые будут представлять ваш реальный контент. Несколько изображений разного размера, текстовые файлы – скрипты или просто текст. Какое-то видео.
Не размещайте на сервере index.html, чтобы видеть, какие файлы в нем находятся просматривая исходный домен в браузере.

Сконфигурируйте CDN. Установите на CDN опцию различать адреса с различными строками запроса как уникальные (т. е. различать file.jpg?123 и file.jpg?456, в Айри.рф это опция «Кэшировать со строкой запроса»). Обычно этот режим установлен на CDN по умолчанию, но все-таки проверьте. Также убедитесь, что CDN пересылает все заголовки от исходного сервера клиенту, включая заголовок X-Tb-Time.

Сконфигурируйте DNS. Установите также низкое значение TTL на сервере порядка 300 секунд, это пригодится позже при тестировании реакции CDN на отсутствие ответа от сервера.

Тестирование поведения CDN: примеры


Здесь адрес dummy.mydomain.com используется как адрес CDN и dummy.origin.com – адрес исходного сервера. Протестируем, используя cURL. Запустим cURL со следующими опциями: curl -vo /dev/null и будем отправлять запрос GET, и в ответ видеть только заголовки, отправляя основное тело страницы на /dev/null.

Не используйте –I флаг для отправки запроса HEAD. CDN может обрабатывать запросы HEAD совершенно иначе, чем GET. Кроме того, ваши пользователи вряд ли будут слать на сервер HEAD, их запросы будут преимущественно GET.

Не кэшировать и получать все данные из исходного сервера


Это не самый типичный пример использования CDN, но если вам надо какую-то часть контента оставить не кэшированной, то необходимо убедиться, что здесь все работает как нужно. Вопрос тут в том, какую директиву Cache-Control правильнее будет использовать. Основываясь на RFC 7234 кажется логичным использовать Cache-Control:no-store. RFC пишет:
Директива no-store указывает, что данные не должны сохраняться в кэше как для запроса, так и для ответа. Касается как публичного кэша, так и локального.

Давайте попробуем:

curl -vo /dev/null 'http://dummy.mydomain.com/15kb.jpg?Cache-Control=no-store'

Ниже вы видите заголовки ответа для наших тестов CDN Fastly. Удивительно, но Fastly не уважает no-store и кэширует данные после того, как не обнаруживает их во время первого запроса в своем кэше.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Cache-Control: no-store
Content-Type: image/jpeg
Last-Modified: Tue, 21 Mar 2017 10:13:25 GMT
X-Tb-Time: 2017-03-30 14:39:11.358951299 +0000 UTC
Content-Length: 15887
Accept-Ranges: bytes
Date: Thu, 30 Mar 2017 14:39:23 GMT
Via: 1.1 varnish
Age: 12
X-Served-By: cache-ams4136-AMS
X-Cache: HIT
X-Cache-Hits: 1
X-Timer: S1490884763.605627,VS0,VE0
Vary: Accept-Encoding

Может быть, сработает no-cache или max-age=0? Нам надо, чтобы CDN не кэшировала ответы и не слала условные запросы исходному серверу.

Тестирование показало, что no-cache так же не работает – CDN продолжает кэшировать ответы, а вот max-age=0 сработало.

Кэшировать на 300 секунд, затем сверить с оригиналом


Дать CDN задание кэшировать файл на 300 секунд довольно просто: Cache-Control=max-age=300. Вопрос тут вот в чем: когда время жизни файла в кэше истечет, какой тип запроса будет посылать CDN серверу – условный или безусловный? Кто-то может сказать, что условный запрос тут будет оптимальным, поскольку если файл не устарел, сервер скажет 304 – «нет, файл не устарел, можно брать его из кэша», и CDN быстренько выдаст клиенту имеющуюся у нее копию. Это быстрее, чем если бы сервер начал пересылку всего файла сам.

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

curl -vo /dev/null 'http://dummy.mydomain.com/15kb.jpg?Cache-Control=max-age=300'

Fastly и CDNetworks шлют условные запросы. Айри.рф и StackPath шлет серверу безусловные запросы, обновляя кэш новой версией файла. Это видно из логов исходного сервера и из значения X-Tb-Time поля в заголовке ответа CDN клиенту. Тестировалось также Cache-Control=max-age=300,must-revalidate, но безуспешно.

HTTP/1.1 200 OK
Date: Fri, 31 Mar 2017 11:20:16 GMT
Content-Type: image/jpeg
Content-Length: 33956
Access-Control-Allow-Origin: *
Cache-Control: max-age=20,must-revalidate
Last-Modified: Fri, 31 Mar 2017 09:49:42 GMT
X-Tb-Time: 2017-03-31 11:20:16.091275242 +0000 UTC
Server: NetDNA-cache/2.2
Accept-Ranges: bytes
X-Cache: EXPIRED
Connection: keep-alive

Кэшировать на 5 минут, разрешить выдавать просроченную версию еще 15 минут


curl -vo /dev/null 'http://dummy.mydomain.com/15kb.jpg?Cache-Control=max-age=300&stale-while-revalidate=900&stale-if-error=900'

Здесь важно протестировать три ситуации:

1. Исходный сервер не найден DNS (NXDOMAIN)


Еще долгое время после того, как DNS TTL истек в кэше для нашего сервера, CDN все еще выдавала сохраненный у нее контент. Это хорошо.

Что более интересно, CDN при этом продолжала обращаться к исходному серверу за свежими версиями контента. Такое ощущение, что вместе с контентом она хранит и IP-адреса, с которых он получен, и таким образом была «прикрыта» ошибка DNS, которая привела к невозможности вычисления IP. Или может быть Fastly поддерживает долгоживущий коннект с сервером? Тут надо смотреть глубже.

2. Исходный сервер выдает ответ 400


Что-то на сервере пошло не так, и он начал выдавать ошибку 400 Bad request. Ожидалось, что CDN будет обрабатывать в таком случае stale-if-error, но она просто транслировала ответ 400 клиенту. Как выяснилось, ожидания оказались неверными, так как в RFC 5861 «HTTP Cache-Control расширения для устаревшего контента» указано:
Ошибка, это ситуация, в которой возвращен 500, 502, 503 или 504 HTTP ответ.

А 400 не является ошибкой, по умолчанию.

3. Сервер сбрасывает весь входящий трафик


В третьем сценарии была заменена DNS-записи сервера, привязав домен к адресу 72.66.115.13. Этот адрес связан с blackhole.webpagetest.org. Это специальный адрес для тестирования ситуаций, когда сервер не отвечает ни на какой запрос.

Стал ли CDN выдавать хранящийся у нее контент? Нет, она стала выдавать ответ 503 после примерно 1 секунды ожидания, и этот 503 ответ содержал заголовок Retry-After: 0. Айри.рф в описываемой ситуации отвечает с заголовков Retry-After: 500 и имеет настраиваемые времена ожидания соединения и ответа от хостинга сайта.

Это то, что заложено в настройках по умолчанию для прокси. В документации написано: «Если Varnish не может связаться с исходным сервером по любой причине – в любом случае генерируется ответ 503». Это свойство унаследовано от Varnish-кода, на основе которого создано большинство CDN прокси.

StackPath в подобной ситуации может выдавать архивный контент, но эта ситуация должна быть сконфигурирована пользователем для ошибок 404, 502, 503 и т. д. Тем не менее, StackPath не обрабатывает ситуацию NXDOMAIN или blackhole.

Итак, пользуйтесь Dummy Origin, чтобы убедиться, что ваш CDN-провайдер работает правильно. Это бесплатный инструмент с открытым исходным кодом.
Поделиться с друзьями
-->

Комментарии (1)


  1. m11
    17.05.2017 09:09
    +1

    Опечатки: s/Brotly/Brotli/g и там же рядом Chrome