TLDR:
В чем разница между
Public, max-age=<VALUE>иmaxage=<VALUE>, s-maxage=<VALUE>синтаксис управления кешем?
Вопрос:
Для одного из моих проектов я хочу снизить нагрузку на сервер с помощью Cache-control http-заголовка. Этот проект размещен как бессерверная функция на Vercel и вызывает GitHub GraphQL API на серверной части для получения информации о пользователе GitHub. И Vercel API , и GitHub API ограничены по скорости, поэтому я ищу лучший заголовок, чтобы предотвратить превышение этих ограничений. Для этого я сейчас использую следующий заголовок Cache-control:
public, max-age=14400, stale-while-revalidate=86400
Согласно документации Mozilla, этот заголовок должен поддерживать актуальность как приватного кеша браузера, так и кеша сервера в течение 4 часов, в то время как устаревший кеш можно повторно использовать в течение 1 дня, пока он проверяется на сервере. Кроме того, поскольку я не использую заголовок аутентификации, я смогу даже удалить ключевое слово Public.
Однако документация по кешу Vercel рекомендует следующий заголовок:
maxage=0, s-maxage=14400, stale-while-revalidate=86400
Основываясь на документации Vercel и этом вопросе о переполнении стека, я считаю, что следующий заголовок лучше всего подходит для снижения нагрузки как на Vercel, так и на GitHub:
maxage=14400, s-maxage=7200, stale-while-revalidate=86400
Насколько я понимаю, с этим заголовком кеш будет свежим в течение 4 часов для отдельных пользователей, в то время как сервер Vercel обновляет кеш каждые 2 часа, а устаревший кеш можно повторно использовать в течение 1 дня, пока он проверяется на сервере.
Поскольку я не уверен в разнице между синтаксисом Public, max-age=<VALUE> и maxage=<VALUE>, s-maxage=<VALUE>, я быстро захотел перепроверить свое понимание.
Согласно документации Mozilla, эти два синтаксиса должны приводить к одинаковому поведению, если <VALUE> равно между свойствами maxage и s-maxage. Однако в документации Symfony говорится, что флаг s-maxage запрещает кешу использовать устаревший ответ в сценариях устаревших при ошибке. Поэтому мой вопрос: в чем точная разница между этими двумя синтаксисами и какой из них вы бы порекомендовали для снижения нагрузки как на API Vercel, так и на GitHub?





Рекомендуемые Vercel заголовки кеша хорошо подходят для минимизации количества вызовов API:
Cache-Control: maxage=0, s-maxage=N
s-maxage используется для управления кэшированием Vercel Edge Network, что позволяет ему обслуживать кэшированные ответы, а не вызывать бессерверную функцию. Насколько я знаю, у него нет собственных ограничений скорости.
Конечно, у вас, вероятно, есть и другие цели кэширования, помимо сокращения вызовов API. Таким образом, вы также можете использовать maxage, чтобы разрешить кэширование браузера, чтобы уменьшить задержку для ваших пользователей.
Также рекомендуется использовать stale-while-revalidate, но учтите, что это всего лишь механизм для уменьшения задержки. Повторная проверка все еще происходит, поэтому она не повлияет на количество вызовов API.
Что касается public, это означает «что любой кеш МОЖЕТ хранить ответ, даже если ответ обычно не кешируется или кешируется только в частном кеше». Если ваш ответ уже кэшируется общедоступным кешем, эта директива не будет иметь никакого эффекта.
Кроме того, вы знакомы с stale-if-error ограничением, о котором говорится в документации Symfony ? Это обсуждалось в этой проблеме GitHub, но я не могу найти точную логику в документации, в которой говорится, что повторное использование stale-if-error запрещено, когда s-maxage включен. Я думаю, что в моем кеше stale-while-revalidate будет иметь приоритет над этим поведением, но мне любопытно поведение stale-if-error по умолчанию.
Короче говоря, каким будет поведение при использовании заголовка maxage=14400, s-maxage=7200, stale-if-error=86400, stale-while-revalidate=86400? Насколько я понял, из документации, которую вы дали, поскольку используется s-maxage, кеш хранится как в браузере, так и в CDN с разной частотой обновления времени. Если кеш в браузере уже не свежий, он будет запрошен из CDN. Если кеш в CDN больше не обновляется, он вернет устаревший ответ и обновит его на сервере. Если в CDN возникает ошибка, устаревший кеш обслуживается до 1 дня.
@rickstaa: 1) Как я уже писал здесь, вы не должны ожидать, что браузеры будут использовать s-maxage. 2) Я не знаю, почему авторы стандарта решили сделать s-maxage подразумевающим proxy-revalidate, но, похоже, это действительно так. Однако директивы stale- были добавлены позже, и, к сожалению, в спецификациях не указано, как они взаимодействуют с директивами -revalidate. И поскольку Vercel рекомендует использовать s-maxage и stale-while-revalidate вместе, они, очевидно, не предотвращают показ устаревших результатов при использовании s-maxage. Так что я не уверен.
@rickstaa: 3) Да, эта интерпретация верна, с добавлением того факта, что браузер также будет использовать stale-while-revalidate, поэтому кеш браузера вернет устаревший результат, пока он проверяется с помощью CDN.
Ах, хорошее замечание о флаге stale-while-revalidate! Еще раз спасибо за ваш подробный ответ.
Я только что нашел в документации Vercel, что они не поддерживают флаг proxy-revalidate. Возможно, по причинам, описанным выше. Так что при развертывании Vercel у людей не должно быть проблем с флагом stale-if-error.
Удивительно! Спасибо за ваш подробный ответ. Вы правы, Vercel в настоящее время не имеет ограничений на использование пограничного кеша (см. документацию Vercel ). Поэтому добавление
maxageиstale-while-revalidateнеобходимо только для улучшения взаимодействия с пользователем. Могу я спросить вас, как ведет себя кеш браузера, когда указано толькоs-maxage. Из документации похоже, что и браузер, и CDN используют значениеs-maxage.