Перенос генерации миниатюр с PHP-бэкенда на Cloudflare Workers позволил полностью снять нагрузку с CPU на сервере-источнике (origin) для видеохостинга, который обслуживает миллионы изображений в день. Этот переход также перенес задержку обработки изображений из дата-центра на edge, что сократило время отклика и сделало затраты на трафик предсказуемыми.

Почему старая модель перестала работать

Сайт — платформа, отображающая десятки тысяч видео, — встраивает до 40 миниатюр на одну страницу. Каждая миниатюра изменяет размер по запросу с помощью PHP-скрипта, который считывает исходный файл и масштабирует его. Когда на сайт заходили поисковые роботы, бэкенд-сервер зависал.

Edge-обработка решает пять основных задач

API для генерации миниатюр промышленного уровня должен обеспечивать:

  • Fan-in — получение исходных изображений с множества сторонних хостов.
  • Fan-out — создание нескольких размеров (например, карточки 320 px, hero-изображения 640 px).
  • Согласование форматов — отдача WebP или AVIF, если браузер их поддерживает, для экономии трафика.
  • Кэширование — обеспечение того, чтобы первый запрос мог быть «дорогим», но каждый последующий был бесплатным.
  • Безопасность — предотвращение злоупотреблений сервисом для обработки произвольных изображений.

Cloudflare Workers решают каждую из этих задач, не нагружая CPU сервера-источника:

  1. Близость — Workers работают в дата-центрах рядом с пользователем, поэтому обработанное изображение проходит более короткий путь.
  2. Встроенное изменение размера изображений — функция Image Resizing на платформе берет на себя работу с пикселями, избавляя от необходимости использовать кастомные библиотеки.
  3. Cache API — Workers сохраняют измененное изображение на edge; после первого запроса edge отдает его напрямую.
  4. Программируемая безопасность — небольшой скрипт проверяет HMAC-подписи, применяет белый список (allow-list) хостов и размеров, а также нормализует ключи кэша для предотвращения отравления кэша (cache poisoning).

Как работает система

  1. Источник создает подписанные URL — бэкенд хранит секретный ключ и добавляет HMAC-подпись к каждому запросу миниатюры. URL также включает желаемую ширину и формат.
  2. Worker проверяет подпись — при получении запроса Worker пересчитывает HMAC с использованием общего секрета. Если подпись отсутствует или неверна, запрос отклоняется, что предотвращает злоупотребления.
  3. Применение белого списка — скрипт проверяет, входит ли хост источника в предопределенный список и является ли запрашиваемая ширина одним из поддерживаемых размеров. Это предотвращает кэширование вредоносных хостов.
  4. Нормализация ключа кэша — сама подпись удаляется из ключа кэша; ключ содержит только URL источника, ширину и формат. Это повышает вероятность того, что разные пользователи, запрашивающие одно и то же изображение, попадут в одну и ту же запись кэша.
  5. Загрузка и изменение размера на edge — если изображение еще не кэшировано, Worker загружает оригинал со стороннего хоста, запускает Image Resizing API и сохраняет результат в кэш на edge.
  6. Прогрев кэша — после каждого обхода поисковыми роботами легкий Python-скрипт делает предварительные запросы новых миниатюр. Таким образом, первый реальный пользователь получает ответ из кэша, а не ждет завершения операции изменения размера.

Измеримый результат через месяц

  • Нагрузка на CPU источника для изображений — упала до нуля; бэкенд больше никогда не обрабатывает байты изображений.
  • Скорость отдачи HTML — заметно улучшилась, так как сервер больше не блокируется на задачах по обработке изображений.
  • Процент попаданий в кэш на edge (cache hit rate) — достиг 96%, что означает, что почти каждый запрос удовлетворялся на edge без обращения к бэкенду.
  • Задержка (latency) — снизилась, так как изображения теперь отдаются из дата-центра рядом с пользователем, а не из центрального источника.
  • Предсказуемость трафика — благодаря кэшированию на edge исходящий трафик от источника стабилен и его легко прогнозировать.

Итог

Перенос генерации миниатюр на Cloudflare Workers превратил узкое место, связанное с нагрузкой на CPU, в практически бесплатный edge-кэш. Теперь источник только выдает подписанные URL, в то время как edge берет на себя загрузку, изменение размера, согласование форматов и отдачу кэшированных результатов. Для любого сайта, сильно зависящего от изображений — особенно для видеоплатформ, отображающих десятки миниатюр на странице — подход edge-first обеспечивает более быструю загрузку страниц, предсказуемые затраты и четкое разделение между тем, «что показывать» (источник), и тем, «как это доставить» (edge).