Цель
Всегда обслуживать контент из кэша CDN EDGE, независимо от его устаревания. Если возможно, обновите sh в фоновом режиме.
Проблема
У меня есть приложение Next JS, которое отображает некоторые компоненты React на стороне сервера и доставляет их в клиент. В этом обсуждении давайте просто рассмотрим мою домашнюю страницу, которая не аутентифицирована и одинакова для всех.
Мне бы хотелось, чтобы домашняя страница, отображаемая на сервере, кэшировалась на узлах EDGE CDN и обслуживалась конечными клиентами из этот кэш как можно чаще или всегда.
Из того, что я прочитал, CDN (например, Fastly), которые должным образом поддерживают настройки заголовка, связанные с кэшем, такие как Surrogate-Control
и Cache-Control: stale-while-revalidate
, должны быть в состоянии сделать это, но на практике я не вижу, как это работает, как я ожидал. Я вижу либо:
- запросы пропускают кеш и возвращаются к источнику, когда предыдущий запрос должен был согреть его
- запросы обслуживаются из кеша, но никогда не обновляются, когда origin публикует новое содержание
Пример
Рассмотрим следующую временную шкалу:
[ T0] - Visitor1 запрашивает www.mysite.com
- Кэш CDN полностью холодный, поэтому запрос должен go вернуться к моему источнику (AWS Lambda) и заново вычислить домашнюю страницу. Ответ возвращается с заголовками Surrogate-Control: max-age=100
и Cache-Control: public, no-store, must-revalidate
. Посетителю1 затем подают домашнюю страницу, но им пришлось ждать колоссальные 5 секунд! YUCK! Пусть никому другому посетителю не придется постигать та же участь.
[T50] - Запросы посетителя 2 www.mysite.com
- CDN Кэш содержит мой документ и немедленно возвращает его посетителю. Им оставалось только ждать 40 мс! Потрясающие. На заднем плане CDN обновляет последнюю версию домашней страницы моего происхождения. Оказывается, он не изменился.
[T80] - www.mysite.com
публикует новый контент на домашней странице, что делает любой кэшированный контент действительно устаревшим. V2 сайта теперь активен!
[T110] - Visitor1 возвращается к www.mysite.com
- С точки зрения CDN, прошло всего 60 лет с момента запроса Visitor2, что означает фоновую ссылку sh, инициированное Visitor2, должно было привести к появлению устаревшей копии домашней страницы <100 с в кэше (хотя V1, а не V2 домашней страницы). Посетитель1 обслуживается устаревшей домашней страницей V1 из кеша. Гораздо лучший опыт для Visitor1 на этот раз! Этот запрос инициирует фоновый refre sh устаревшего содержимого в кэше CDN, и источник на этот раз возвращает V2 веб-сайта (который был опубликован 30 с go). </p>
[T160 ] - Visitor3 посещений www.mysite.com
- Несмотря на то, что он новый посетитель, кэш CDN теперь свободен sh от самого последнего триггера фонового обновления Visitor1 sh. Посетителю 3 обслуживается кэшированная домашняя страница V2.
...
Пока хотя бы один посетитель посещает мой сайт каждые 100 с (потому что max-age=100
), ни один посетитель не будет терпеть ожидание время полного обхода до моего происхождения.
Вопросы
1. Это разумный вопрос современного CDN? Я не могу себе представить, что это намного сложнее, чем всегда возвращаться к источнику (без кеша CDN), но я изо всех сил пытался найти документацию у любого провайдера CDN о правильном способе сделать это. Сейчас я работаю с Fastly, но хочу попробовать и другие (сначала я попробовал Cloudflare, но прочитал, что они не поддерживают stale-while-revalidate
)
2. Что правильные заголовки для этого? (при условии, что провайдер CDN их поддерживает) Я поиграл с Surrogate-Control: maxage=<X>
и Cache-Control: public, s-maxage=<X>, stale-while-revalidate
в Fastly и Cloudflare, но ни один из них, похоже, не делает это правильно (запросы хорошо в максимальный таймфрейм не принимает изменения в источнике, пока не будет пропущен кэш).
3. Если это не поддерживается, существуют ли вызовы API, которые могут позволить мне выполнить PU SH содержимое обновляется в слое кеша моего CDN, фактически говоря: «Эй, я только что опубликовал новый контент для этого ключа кеша. Вот оно! "
Я мог бы использовать работника Cloudflare для реализации своего рода кэширования самостоятельно, используя их хранилище KV, но я подумал, что мне нужно немного больше исследовать, прежде чем реализовывать решение кода, которое кажется проблемным. быть довольно распространенным явлением.
Заранее спасибо!