如果你每天在一个后端 Lambda 或一个小 K8s pod 上生成几百份 PDF,架构其实无所谓。怎么做都行,怎么做都够快。
到了规模上情况就变了。一旦每天产出文档破万——任何稍有动静的电商平台、物流承运商、BNPL 服务、薪资服务、开票平台都在这个量级——三个指标会变得敏感:
- 冷启动延迟——总有什么在某处刚冷下来。
- 区域延迟——你的客户不在你的源站旁边。
- 单次生成算力——你每天都在为它付费十几万次。
本文走一遍每条曲线在 ~1 万次/天 之后是怎么变形的,以及为什么像 gPdf 这样的边缘部署 PDF 生成器本质上是不同的解决方案类别——而不是「同一种东西、只是更快」。
1. 冷启动税与并发叠加
冷启动不只是烦人——它是你并发曲线的函数。典型场景:
- 你按平均流量配 N=10 个温热容器。
- 3× 流量峰值袭来(黑五、发薪日、季末)。
- 20 个新容器冷启动来吸收峰值。每个要 1.5 到 2.5 秒启 Chromium / Prince / 你的运行时。
- 接下来 30 秒,这些新容器以 p99 = 2 秒服务,把全局 p99 一起拽下水。
- 你下游的超时预算(整个订单流水线大概 5–10s)现在被 PDF 生成吃掉了。
流量平稳时这没事。流量尖刺时残忍——而 PDF 流量永远是尖刺的:发票在账单周期边界发出、运单在承运商揽收时发出、对账单月末发出。
边缘部署对应方案:Cloudflare Worker isolate 冷启动 5–20 ms,不是 1.5–2.5 秒。没有容器要起、没有 JVM/V8 要初始化、没有浏览器要引导——WASM 模块加载到一个已经活着的进程里。冷启动不再是你需要架构防御的东西。
具体到 gPdf,跨我们所有压测看到的最坏冷启动约 12 ms——而且只是新分配 isolate 的第一次请求。同一个 isolate 上后续请求连这点也省。
2. 区域延迟是真的,即使对「快」请求也是
悉尼到 us-east-1 单程 200 ms,你的代码还没动。圣保罗到 eu-west-1 ~190 ms。孟买到 us-east ~220 ms。
而且这是单方向。所以一个集中部署的 PDF API 服务端 300 ms 渲染,从悉尼客户视角看是:
client → us-east : 200 ms
us-east 渲染 : 300 ms
us-east → client : 200 ms
总 wall-clock : 700 ms
对于交互流(「在发出前预览发票」)很痛。对于高量级后端任务察觉不到。
边缘部署对应方案:Cloudflare 跑在 300+ 城市。距悉尼客户最近的 colo 大约 5 ms。同样的渲染变成:
client → SYD colo : 5 ms
SYD 渲染 : 4 ms
SYD → client : 5 ms
总 wall-clock : 14 ms
对交互流是 50× 改善。对后端任务等价,但交互式 PDF 预览(「让我看看发出前长啥样」)从卡顿变得免费。
隐藏的二阶收益:如果你的 PDF API 跑在边缘,你可以把邻近逻辑也搬过来——结账 PDF 预览、限流、鉴权。每搬一块到边缘,就从你的热路径上拿走一次往返。
3. 单次渲染成本是无声叠加的账单
10 万次/天 的 Lambda 价格数学:
- Puppeteer 约 600 ms wall, 1024 MB 内存:每月仅算力 ~$240,还没算流量。
- DocRaptor 按 $89/100K 页档:10 万/天(= 月 300 万)= 每月 ~$2,670。
- gPdf 按 $5/100K 页档:10 万/天 = 每月 ~$150;如果刚好月 10 万就 $5。
成本差距随规模扩大不会缩小——只会拉宽。100 万次/天:
- Puppeteer 基础设施:~$2,400/月 + 运维 + 值班
- DocRaptor:~$26,700/月
- gPdf:$1,500/月(5× 的 10 万/天 档,假设按公开价格梯度协商体量)
常见反应:「实际节省肯定没这么大——肯定有什么藏起来了。」 经验上没有。PDF 生成的成本驱动是渲染器的算力足迹。一旦把 600 MB Chromium 进程换成 4 MB WASM 模块,单次成本下降约 100×,账单跟着走。
我们能做这件事而不破产:底层 Cloudflare Workers Bundled 价格大约 $0.50/百万次请求。我们的渲染器单次 ~1.5 ms CPU,单次成本货真价实是亚分级。我们温和加价做到可持续的生意,你仍然看到 18× 差距。
“边缘部署” 实际给你买什么
三件事,没一件只是营销话术:
任意负载下的可预测延迟
因为没有按请求的启动成本,你的 p50 和 p99 离得很近。我们通常看到流量峰顶 p99 在 p50 的 3× 以内——而 Puppeteer 在冷启动暴风时 p99 能到 p50 的 10×。
一个可部署制品,到处一样
.wasm 模块部署到每个 Cloudflare colo 都一样。不存在「悉尼池热不热」这个问题——每个 isolate 在毫秒内启动模块,提供完全一致的服务。这在运维上比维护区域 Lambda 并发预留要简单得多。
一条嵌入的路径
如果你以后想把 gPdf 跑在客户的边界内(他们的 VPC、隔离集群、气隙内网),同一个 WASM 模块就能用。这是「我们做了 SaaS」和「我们出了能在任何地方跑的技术」的区别。
这个模型在哪里失效
边缘不是免费魔法——有些工作负载集中部署会赢:
- 多秒级渲染。 单份 PDF 要 30 秒(巨型财务对账单、科学报告),你更适合长进程容器加持久状态,而不是和边缘 CPU 上限搏斗。
- 需要其他数据库的渲染。 如果渲染要 JOIN 三张 OLAP 表,你想让渲染器在数据库旁边而不是在边缘。(解:先做 JOIN,把 JSON 发到边缘做实际渲染。)
- 需要后处理的输出。 加水印、签名、归档——如果你的后处理流水线多步且有状态,边缘渲染的「无状态」属性变成税而不是特性。
其他一切——也就是 B2B 发票/运单/收据流量的绝大多数——边缘在每条重要的轴上都赢。
什么时候该停止容忍当前架构
简单清单。如果你能勾上三条,迁移数学已经倒过来:
- 每月 PDF 基础设施成本越过 $300。
- 正常流量下 PDF p99 延迟 > 800 ms。
- 你撞过一次冷启动事故,影响了客户。
- 你花过 4 小时以上调试缺失的 CJK / RTL / emoji 字形。
- 你在交互流里生成 PDF(预览、屏幕下载)。
- 你在不止一个地理区域运营。
前三条同时成立,意味着你正在同时付出成本和承受延迟风险。后三条意味着集中式渲染器正在主动限制你本可以做的产品决策。
任何一条听起来熟悉,在线体验 都能在你浏览器里 5 ms 内生成一张样本发票——直接看结果。