将缩略图生成从 PHP 后端迁移到 Cloudflare Workers,为一家每天提供数百万张图片的视频托管网站消除了源服务器上的所有 CPU 负载。这次切换还将图像处理延迟从数据中心推向了边缘,大幅缩短了响应时间,并使带宽成本变得可预测。
为什么旧模式会失效
该网站是一个展示数万个视频的平台,单个页面最多会嵌入 40 个缩略图。每个缩略图都由一个 PHP 脚本按需进行调整大小,该脚本读取原始文件并进行缩放。当爬虫访问该网站时,后端服务器就会陷入卡顿。
边缘处理解决了五个核心需求
一个生产级的缩略图 API 必须处理:
- Fan-in(聚合) – 从许多第三方主机拉取源图像。
- Fan-out(分发) – 生成多种尺寸(例如:320px 卡片、640px 主图)。
- 格式协商 – 当浏览器支持时,提供 WebP 或 AVIF 以节省带宽。
- 缓存 – 确保第一次请求可能成本较高,但随后的每一次请求都是免费的。
- 安全性 – 防止任何人滥用该服务来处理任意图像。
Cloudflare Workers 在不占用源站 CPU 的情况下解决了上述每个问题:
- 接近性 – Workers 在靠近用户的数据中心运行,因此处理后的图像传输路径更短。
- 内置图像缩放 – 该平台的 Image Resizing 功能负责像素级操作,无需自定义库。
- Cache API – Workers 将调整大小后的图像存储在边缘;在第一次请求之后,边缘会直接提供该图像。
- 可编程安全性 – 一个小型脚本用于验证 HMAC 签名、强制执行主机名和宽度的白名单,并规范化缓存键以避免缓存中毒。
系统工作原理
- 源站创建签名 URL – 后端持有密钥,并在每个缩略图请求中附加 HMAC 签名。URL 还包含所需的宽度和格式。
- Worker 验证签名 – 收到请求后,Worker 使用共享密钥重新计算 HMAC。如果签名缺失或错误,请求将被拒绝,从而阻止滥用。
- 白名单强制执行 – 脚本会检查源主机名是否在预定义列表中,以及请求的宽度是否为支持的尺寸之一。这可以防止恶意主机被缓存。
- 缓存键规范化 – 签名本身会从缓存键中剥离;缓存键仅包含源 URL、宽度和格式。这提高了不同用户请求同一图像时命中相同缓存条目的概率。
- 边缘获取与缩放 – 如果图像尚未缓存,Worker 会从第三方主机获取原始图像,运行 Image Resizing API,并将结果存储在边缘缓存中。
- 缓存预热 – 在每次爬虫访问后,一个轻量级的 Python 脚本会预先请求最新的缩略图。因此,第一个真实用户收到的将是缓存响应,而不是等待缩放操作。
一个月后的可衡量影响
- 图像处理的源站 CPU 占用 – 降至零;后端再也不需要处理图像字节。
- HTML 服务速度 – 显著提升,因为服务器不再因图像处理而阻塞。
- 边缘缓存命中率 – 达到 96%,这意味着几乎每个请求都直接从边缘获取,无需后端获取。
- 延迟 – 降低,因为图像现在是从靠近用户的数据中心提供,而不是从中心源站提供。
- 带宽可预测性 – 通过边缘缓存,源站的出站流量变得稳定且易于预测。
总结
将缩略图生成任务卸载到 Cloudflare Workers,将一个受 CPU 限制的瓶颈转变为近乎零成本的边缘缓存。现在,源站仅负责签发签名 URL,而边缘负责获取、缩放、格式协商和提供缓存结果。对于任何高度依赖图像的网站——尤其是每页显示数十个缩略图的视频平台——这种“边缘优先”的方法能够提供更快的页面加载速度、可预测的成本,以及“展示什么”(源站)与“如何交付”(边缘)之间更清晰的分离。
