Insights / Технические материалы

Разделите периферийное кэширование публичных изображений и лимиты API

Случай, когда API контента и запросы изображений использовали общий лимит при повторном просмотре. Рассматриваются повторное использование публичных изображений, проверка успешных ответов, границы WAF и приложения, а также проверки в production.

  • Cloudflare
  • Performance
  • Web
Разделите периферийное кэширование публичных изображений и лимиты API
Содержание
  1. Воспроизведение последовательного просмотра с одного изображения
  2. Контент и изображения использовали общий лимит
  3. Повторно используйте только доступные для совместного использования публичные изображения
  4. Сохраняйте только проверенные ответы 200
  5. Независимо обрабатывайте лимиты динамического API
  6. Проверяйте содержимое изображений в production

В дневниках и каталогах с изображениями каждое переключение даты или страницы вызывает запросы и к API контента, и к изображениям. Мы описываем случай, когда при повторном просмотре изображения перестали загружаться, не раскрывая рабочие URL, внутренние маршруты и значения лимитов.

Воспроизведение последовательного просмотра с одного изображения

Повторно запрашивайте одно публичное изображение и сравнивайте хеш тела, статус и состояние кеша. Затем загружайте текст и несколько изображений обычной навигацией, проверяя учёт запросов в лимите. Одного HIT недостаточно: проверяйте содержимое изображения и защиту API.

Cloudflare Cache API:Условное чтение и локальность кеша

Контент и изображения использовали общий лимит

В этом случае запросы к динамическому API и GET-запросы публичных изображений учитывались одним правилом ограничения запросов WAF. Даже обычное переключение страниц могло вызвать несколько запросов одновременно: контент загружался, а изображения могли попасть под ограничение.

Добавление периферийного кэша изображений не помогает запросам, которые WAF блокирует до их попадания в кэш. Мы отдельно изменили нагрузку на источник и типы запросов, учитываемые в одном лимите. Существующие ограничения приложения и quota генерации сохраняются для своих задач.

Повторно используйте только доступные для совместного использования публичные изображения

Рассматриваемые здесь изображения неизменны: один и тот же публичный asset ID всегда возвращает одинаковое содержимое. Сначала мы проверяем формат asset ID, границу запроса и конфигурацию Service Binding, и только затем ищем запись кэша по тому же host и asset ID. Даже прогретый кэш не позволяет пропустить эти проверки на входе.

Параметры query string, не влияющие на содержимое, и заголовки запроса конечного пользователя не создают отдельные варианты кэша для одного изображения. Это допустимо только потому, что изображения публичные и неизменные. Такой подход нельзя без изменений применять к приватным изображениям, содержимое которых зависит от пользователя или организации.

Сохраняйте только проверенные ответы 200

При промахе кэша изображение запрашивается через приватный Service Binding. Мы проверяем HTTP status, Content-Type изображения, Content-Length и тело ответа, сохраняя только ответ 200, который соответствует этим условиям. Частичные ответы, пустые тела, неверные metadata и ответы об ошибке не сохраняются.

Сохранение данных изображения отличается от ответа 304 при совпадении ETag. Записи в кэш планируются через waitUntil; сбои чтения или записи кэша не должны мешать вернуть корректное изображение, полученное от источника. Если следующий запрос сможет использовать кэш, обращение через Service Binding можно пропустить.

Cloudflare Cache API описывает условные запросы с ETag и особенности кэша для каждого центра обработки данных. HIT в одном центре не означает HIT во всех центрах. Заголовки ответа Pages Functions нельзя настроить только через _headers для статических файлов; ими нужно управлять в Function.

Независимо обрабатывайте лимиты динамического API

Защита динамического API — отдельное требование, не связанное с кэшированием изображений. В этом случае GET-запросы публичных изображений исключили из подсчёта WAF, а после применения изменения повторно прочитали целевые динамические API, период лимита, действие и состояние включения. Предыдущую конфигурацию также сохранили для отката.

Выбирайте пороги с учётом числа запросов при обычном просмотре и нагрузки защищаемой операции. Нужно также проверить условия тарифного плана для ограничения запросов Cloudflare. Значение в эксплуатационной заметке репозитория не доказывает, что правило включено в production.

Публичные изображения и динамический API Повторное использование неизменяемых публичных изображений и защиту динамических API проектируйте раздельно. Приватные изображения не входят в область.
  1. GET публичного изображения Проверьте границу запроса и повторно используйте то же изображение из кэша. Сохраняйте только проверенные ответы 200.
  2. Динамический API Защищайте обработку API с помощью WAF и квоты приложения. Эти ограничения независимы от кэширования изображений.

Проверяйте содержимое изображений в production

Модульные тесты проверяли повторное использование одного публичного изображения, разделение по host и asset ID, проверку границы до использования кэша, ответы 304, сбои кэша и ответы, которые нельзя сохранять. После CI мы подтвердили публикацию в production через push в GitHub и работу custom domain, затем сверили HTTP-результат для репрезентативных изображений, состояние HIT или MISS в приложении и hash полученных bytes.

В production мы также последовательно получили содержимое и несколько изображений и подтвердили, что в этих тестовых условиях обычного просмотра запросы не ограничивались. Это проверка ограниченного сценария запросов, а не испытание границы при высокой нагрузке.

Одно лишь отображение состояния кэша не доказывает, что возвращено правильное изображение. Мы отдельно проверяем получение контента, получение изображений, конфигурацию WAF и результат просмотра в UI. Эта запись подтверждает доставку репрезентативных изображений, но не непрерывный просмотр всеми пользователями во всех центрах обработки данных и не прирост производительности под высокой нагрузкой.

О разделении статической и динамической частей сайта см. общую архитектуру Astro и Cloudflare. Об оптимизации доставки изображений, CSS и других ресурсов см. настройку производительности Astro.