news 2026/3/2 3:22:16

Cloudflare Workers与Astro的全球延迟性能实验

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cloudflare Workers与Astro的全球延迟性能实验

Cloudflare Workers 性能:与 Astro 和全球延迟的实验

为何使用 Cloudflare Workers?

Cloudflare Workers 允许托管页面和运行代码,而无需管理服务器。与传统服务器放置在单个或少数几个位置不同,部署的静态资产和代码在全球数据中心(如下方蓝点所示)镜像。这自然提供了更好的延迟、可扩展性和鲁棒性。

其开发者平台还超越了“Workers”(计算部分),包括存储、数据库、队列、AI 和许多其他开发者工具。所有这些都提供一个慷慨的免费层和超出部分的合理定价。

撰写本文的原因:发现它相当不错,有良好的使用体验,因此在此介绍。本文并非赞助。开发者有责任交流他们使用的工具,以保持其生态系统活跃。曾见过太多好东西因为缺乏“热度”而被抛弃。

使用 Cloudflare Workers 的好处是:

  • 全球范围内出色的延迟
  • 无限的可扩展性
  • 无需维护服务器
  • 数据、文件、AI 等的进一步工具
  • GitHub 拉取请求预览 URL
  • 免费层对大多数业余项目足够好

何时不使用它

与所有工具一样,它有它擅长的用例,也有不适合的用例。理解底层技术非常重要。基本上,它会将整个应用打包为脚本并在运行时动态评估。如果您的 API 和使用的框架是轻量级和极简主义的,它会很快并且效果很好。然而,在以下用例中不建议使用:

  • 大型复杂应用:评估您的 API/SSR 脚本的成本会随着应用的增大而增加。它变得越大,整个调用就越低效。还有一些限制是关于“脚本”可以有多大。尽管过去已经多次提高此限制,但它效率极低的事实将始终存在。因此,在选择依赖项/框架时要小心,因为它们可能迅速使您的代码库膨胀。
  • 资源消耗大:由于其性质,它不适合需要大量 CPU/内存/时间的计算,如统计模型或科学计算。大型缓存也有问题。等待长时间运行的异步服务器端请求是可以的,执行在中间暂停,不计入执行时间。
  • 长连接:这也是有问题的。应该使用轮询而不是保持连接开放。

换句话说:“越轻量越好!”

很难说什么足够小,什么时候变得太大。这更适合于适度大小的小型自包含微服务。即使使用断点调试也可能变得具有挑战性。对于此类大型应用程序,传统的服务器部署会更合适。

我们将构建什么?

一个“每日名言”Web 应用程序。

目的不是构建一个大型的东西,而是一个简单的概念验证。名言将存储在 KV 存储中并在客户端获取。这样,我们可以测量整个工作的速度以及它是否符合期望。

https://quoted.day 的默认版本有两种风格:

  • https://quoted.day/spa:一个静态页面,异步获取名言文本/作者
  • https://quoted.day/ssr:服务器端渲染,在服务器上渲染带有名言的页面

为了进行实验,会不时交换哪个是默认版本。性能(延迟)可能因您所在的位置以及您获取的内容是“热”还是“冷”而异。在深入研究如何构建此类应用之前,让我们先看看可以预期的性能。

全球延迟基准测试

与在某中心内部测量的、因此相当乐观的内部 Cloudflare 延迟测量不同,我们将使用出色的工具 https://www.openstatus.dev/play/checker 来查看“真实的”外部延迟。

借助此工具,我们可以很好地了解全球各地可观察到的总体延迟。但请注意,澳大利亚、亚洲和非洲的延迟可能有时相当不稳定,会出现“跳跃”。

我们还将分别对多个事物进行基准测试:

  • 静态资产
  • 无状态函数
  • 热 KV 读取
  • 冷 KV 读取
  • KV 写入

此外,每种情况都会进行“两次传递”,以希望在此过程中填充缓存,并仅记录第二次结果。

静态资产

通过获取主页面 https://quoted.day/spa 获得。

区域延迟
🇩🇪 德国法兰克福30ms
🇩🇪 德国法兰克福 (koyeb)31ms
🇫🇷 法国巴黎33ms
🇳🇱 荷兰阿姆斯特丹 (railway)33ms
🇬🇧 英国伦敦31ms
🇸🇪 瑞典斯德哥尔摩32ms
🇫🇷 法国巴黎 (koyeb)31ms
🇳🇱 荷兰阿姆斯特丹54ms
🇺🇸 美国新泽西州西考克斯32ms
🇺🇸 美国弗吉尼亚州阿什本36ms
🇺🇸 美国华盛顿 (koyeb)35ms
🇨🇦 加拿大多伦多50ms
🇺🇸 美国伊利诺伊州芝加哥36ms
🇺🇸 美国加利福尼亚州洛杉矶28ms
🇺🇸 美国加利福尼亚州圣何塞26ms
🇺🇸 美国弗吉尼亚州 (railway)41ms
🇺🇸 美国加利福尼亚州 (railway)49ms
🇺🇸 美国旧金山 (koyeb)29ms
🇸🇬 新加坡 (railway)53ms
🇮🇳 印度孟买95ms
🇺🇸 美国德克萨斯州达拉斯30ms
🇯🇵 日本东京28ms
🇦🇺 澳大利亚悉尼31ms
🇸🇬 新加坡294ms
🇸🇬 新加坡 (koyeb)436ms
🇧🇷 巴西圣保罗252ms
🇿🇦 南非约翰内斯堡559ms
🇯🇵 日本东京 (koyeb)28ms
无状态函数

通过获取端点 https://quoted.day/api/time 获得,该端点仅返回当前时间。

区域延迟
🇬🇧 英国伦敦38ms
🇩🇪 德国法兰克福 (koyeb)32ms
🇳🇱 荷兰阿姆斯特丹 (railway)36ms
🇫🇷 法国巴黎75ms
🇳🇱 荷兰阿姆斯特丹76ms
🇩🇪 德国法兰克福88ms
🇫🇷 法国巴黎 (koyeb)73ms
🇸🇪 瑞典斯德哥尔摩97ms
🇺🇸 美国弗吉尼亚州 (railway)36ms
🇺🇸 美国华盛顿 (koyeb)62ms
🇺🇸 美国新泽西州西考克斯95ms
🇺🇸 美国加利福尼亚州洛杉矶39ms
🇺🇸 美国加利福尼亚州圣何塞25ms
🇺🇸 美国弗吉尼亚州阿什本92ms
🇺🇸 美国德克萨斯州达拉斯90ms
🇨🇦 加拿大多伦多22ms
🇺🇸 美国伊利诺伊州芝加哥108ms
🇮🇳 印度孟买99ms
🇸🇬 新加坡 (railway)45ms
🇯🇵 日本东京27ms
🇺🇸 美国加利福尼亚州 (railway)99ms
🇧🇷 巴西圣保罗89ms
🇦🇺 澳大利亚悉尼26ms
🇸🇬 新加坡220ms
🇺🇸 美国旧金山 (koyeb)26ms
🇿🇦 南非约翰内斯堡540ms
🇸🇬 新加坡 (koyeb)354ms
🇯🇵 日本东京 (koyeb)71ms
热 KV 读取

通过使用端点 https://quoted.day/api/quote/123 从 KV 存储中获取固定名言获得。

区域延迟
🇬🇧 英国伦敦34ms
🇫🇷 法国巴黎39ms
🇳🇱 荷兰阿姆斯特丹 (railway)35ms
🇫🇷 法国巴黎 (koyeb)37ms
🇸🇪 瑞典斯德哥尔摩34ms
🇳🇱 荷兰阿姆斯特丹77ms
🇩🇪 德国法兰克福 (koyeb)103ms
🇨🇦 加拿大多伦多25ms
🇺🇸 美国德克萨斯州达拉斯33ms
🇺🇸 美国华盛顿 (koyeb)55ms
🇩🇪 德国法兰克福168ms
🇺🇸 美国弗吉尼亚州阿什本106ms
🇺🇸 美国加利福尼亚州 (railway)52ms
🇺🇸 美国新泽西州西考克斯122ms
🇺🇸 美国旧金山 (koyeb)33ms
🇺🇸 美国弗吉尼亚州 (railway)123ms
🇿🇦 南非约翰内斯堡43ms
🇮🇳 印度孟买99ms
🇸🇬 新加坡 (railway)88ms
🇺🇸 美国伊利诺伊州芝加哥69ms
🇧🇷 巴西圣保罗99ms
🇺🇸 美国加利福尼亚州圣何塞40ms
🇦🇺 澳大利亚悉尼64ms
🇺🇸 美国加利福尼亚州洛杉矶91ms
🇸🇬 新加坡345ms
🇯🇵 日本东京126ms
🇯🇵 日本东京 (koyeb)65ms
🇸🇬 新加坡 (koyeb)856ms
冷 KV 读取

通过使用端点 https://quoted.day/api/quote 从 KV 存储中获取随机名言获得。

请注意,每次调用将在边缘位置缓存结果一天,随着流量的增加,可能会将冷读取变为热读取。

区域延迟
🇩🇪 德国法兰克福131ms
🇩🇪 德国法兰克福 (koyeb)105ms
🇬🇧 英国伦敦110ms
🇳🇱 荷兰阿姆斯特丹130ms
🇫🇷 法国巴黎145ms
🇸🇪 瑞典斯德哥尔摩134ms
🇫🇷 法国巴黎 (koyeb)127ms
🇳🇱 荷兰阿姆斯特丹 (railway)133ms
🇺🇸 美国新泽西州西考克斯197ms
🇺🇸 美国伊利诺伊州芝加哥201ms
🇺🇸 美国弗吉尼亚州阿什本220ms
🇨🇦 加拿大多伦多243ms
🇺🇸 美国华盛顿 (koyeb)229ms
🇺🇸 美国德克萨斯州达拉斯287ms
🇺🇸 美国弗吉尼亚州 (railway)270ms
🇸🇬 新加坡288ms
🇺🇸 美国加利福尼亚州圣何塞245ms
🇮🇳 印度孟买502ms
🇿🇦 南非约翰内斯堡322ms
🇸🇬 新加坡 (railway)323ms
🇺🇸 美国加利福尼亚州洛杉矶247ms
🇺🇸 美国旧金山 (koyeb)217ms
🇺🇸 美国加利福尼亚州 (railway)300ms
🇧🇷 巴西圣保罗601ms
🇯🇵 日本东京822ms
🇸🇬 新加坡 (koyeb)574ms
🇯🇵 日本东京 (koyeb)335ms
🇦🇺 澳大利亚悉尼964ms

KV 写入

通过调用 quoted.day/api/bump-counter 获得,它创建一个具有 10 分钟过期时间的临时 KV 对。这有点模拟了启动“会话”的概念。

区域延迟
🇫🇷 法国巴黎128ms
🇩🇪 德国法兰克福 (koyeb)151ms
🇩🇪 德国法兰克福147ms
🇫🇷 法国巴黎 (koyeb)194ms
🇳🇱 荷兰阿姆斯特丹145ms
🇸🇪 瑞典斯德哥尔摩240ms
🇬🇧 英国伦敦176ms
🇺🇸 美国德克萨斯州达拉斯212ms
🇺🇸 美国加利福尼亚州 (railway)238ms
🇺🇸 美国华盛顿 (koyeb)305ms
🇺🇸 美国弗吉尼亚州 (railway)295ms
🇺🇸 美国新泽西州西考克斯408ms
🇺🇸 美国弗吉尼亚州阿什本423ms
🇨🇦 加拿大多伦多337ms
🇺🇸 美国伊利诺伊州芝加哥359ms
🇸🇬 新加坡 (koyeb)409ms
🇺🇸 美国加利福尼亚州洛杉矶335ms
🇮🇳 印度孟买347ms
🇺🇸 美国加利福尼亚州圣何塞438ms
🇺🇸 美国旧金山 (koyeb)247ms
🇸🇬 新加坡508ms
🇯🇵 日本东京684ms
🇦🇺 澳大利亚悉尼713ms
🇯🇵 日本东京 (koyeb)734ms
🇳🇱 荷兰阿姆斯特丹 (railway)1,259ms
🇸🇬 新加坡 (railway)1,139ms
🇿🇦 南非约翰内斯堡2,266ms
具有 KV 冷读取的 SSR 页面

最后,在这个测试中,结合读取随机名言(通常会导致冷 KV 读取)并在页面中服务器端渲染它。

区域延迟
🇫🇷 法国巴黎 (koyeb)111ms
🇬🇧 英国伦敦108ms
🇳🇱 荷兰阿姆斯特丹 (railway)125ms
🇫🇷 法国巴黎133ms
🇩🇪 德国法兰克福 (koyeb)139ms
🇩🇪 德国法兰克福146ms
🇸🇪 瑞典斯德哥尔摩142ms
🇳🇱 荷兰阿姆斯特丹70ms
🇺🇸 美国弗吉尼亚州 (railway)151ms
🇺🇸 美国华盛顿 (koyeb)159ms
🇺🇸 美国新泽西州西考克斯201ms
🇺🇸 美国弗吉尼亚州阿什本209ms
🇺🇸 美国伊利诺伊州芝加哥217ms
🇺🇸 美国德克萨斯州达拉斯220ms
🇺🇸 美国加利福尼亚州圣何塞191ms
🇺🇸 美国加利福尼亚州 (railway)201ms
🇨🇦 加拿大多伦多255ms
🇺🇸 美国加利福尼亚州洛杉矶257ms
🇺🇸 美国旧金山 (koyeb)268ms
🇮🇳 印度孟买422ms
🇯🇵 日本东京332ms
🇸🇬 新加坡284ms
🇧🇷 巴西圣保罗327ms
🇸🇬 新加坡 (railway)632ms
🇸🇬 新加坡 (koyeb)677ms
🇿🇦 南非约翰内斯堡673ms
🇦🇺 澳大利亚悉尼385ms
🇯🇵 日本东京 (koyeb)350ms

观察结果

通过观察数字来推断 KV 的工作方式很有趣。似乎 KV 存储不是主动复制的,而是 KV 对在远程位置“按需”复制。当被缓存时(默认 1 分钟),后续读取很快。此类“热”KV 对的延迟总体上相当不错。这里没有问题。该对在缓存中保留多长时间也可以在 KV get 请求期间使用cacheTtl参数进行配置。然而,增加该值的缺点是,在此期间,此缓存副本不反映其他位置触发的变化/更新。

不出所料,冷读取的延迟更差。从数字中可以推断出的另一件事是,似乎存在一个“源位置”,冷读取的延迟根据到该位置的距离成比例地增加。因此,请注意“在哪里”创建 KV 存储,因为它会影响全球所有未来的延迟。请注意,Workers KV 将来可能会改变,这仅仅是其当前状态的观察。

虽然读操作还可以,但写操作目前相当令人失望。原本期望它也有很好的延迟,写入“边缘”并让传播异步进行,但情况恰恰相反。写入似乎与“源”存储通信。设置一个值所需的时间取决于您距离创建 KV 存储的位置有多远。这有点糟糕,因为设置/更新值是一个非常常见的操作,例如对用户进行身份验证。亲爱的某中心团队,希望将来改进这一部分。

注意事项

如果您开发 Web 应用、发布它并查看它,您可能甚至不会注意到糟糕的延迟。您将面临最佳的延迟,源 KV 存储就在您附近。然而,在地球另一端的人将会有更差的体验。如果那个人有一些缓存未命中或写入,响应时间可能会迅速攀升到几秒钟,然后响应才到达。这不是期望的“分布式”KV 存储的行为方式。让我们明确一点,目前它的行为更像是具有边缘按需缓存副本的集中式 KV 存储。

相当讽刺的是,目前它基本上感觉更像传统的单位置数据库(+缓存)。虽然单个缓存未命中或单个写入的延迟并不严重,但随着多次调用,它可能会迅速累积,尤其是写入量大的 Web 应用,可能会根据其位置面临增加的“迟缓”现象。同样,在使用 Workers 构思 Web 应用时,应牢记在 KV 调用方面保持“极简主义”。

最后,Worker 中还有一个可用的设置:“默认放置”与“智能放置”。两者都尝试过,但在延迟方面没有看到明显变化。我认为这是由于只有单个 KV 存储调用,并且需要时间和流量来收集遥测数据并调整 Workers 的放置。这可能很棒,但对于这个实验,它根本没有效果。

单页应用程序与服务器端渲染

同样,没有一个普遍比另一个更好或更差,答案取决于具体情况。

除了框架和整体架构的强烈差异外,对于最终用户来说,它也有实际的根本差异。看到历史重演也很有趣,互联网最初从服务器渲染页面开始,然后单页应用程序数据获取占据了主导地位,而 SSR 再次兴起,就像过去一样,只是有了新的技术栈。

SSR 实际上是最容易解释的:在服务器端获取所有所需数据,将所有内容放入模板,并将结果页面返回给最终用户。它在服务器端花费一些时间和处理能力,不可缓存,但客户端获得一个“已完成”的页面。

SPA 则相反。虽然 HTML/CSS/JS 是静态的并且被缓存(因此获取很快),但由于需要所有客户端 JavaScript 库,资源通常要大得多。然后开始繁重的工作,获取数据并渲染页面,通常显示一个加载指示器。因此,渲染页面的总时间更长。

然而,之后与 SPA 的交互通常更流畅,因为交互只是与服务器交换数据并对页面进行本地更改。相比之下,SSR 意味着导航和加载新页面。因此,选择 SPA 还是 SSR 更适合取决于页面/应用应该有多“交互”。

作为经验法则,如果它更像静态“网页”,选择 SSR;如果它更像交互式“Web 应用”,选择 SPA。

最后,选择 Astro 作为示例的好处在于,整个频谱都是可能的:静态页面、SPA 和 SSR。

来源

此实验的源代码位于:https://github.com/dagnelies/quoted-day

如果您有 Github 和 Cloudflare 帐户,也可以通过单击此处进行 fork 和部署:
https://deploy.workers.cloudflare.com/?url=https://github.com/dagnelies/quoted-day

它将 fork GitHub 存储库并将其部署在内部 URL 上,以便您可以预览。之后,您可以编辑代码,它将自动部署,等等。

请注意,示例引用了一个 KV 存储,该存储是我的。因此,您必须创建自己的名为 QUOTES 的 KV 存储,并用您的 KV id 替换wrangler.json文件中的 QUOTES KV id。如果希望重现该示例,还必须最初用名言填充它。幸运的是,package.json中有脚本来做到这一点。

此后的所有内容都值得单独写一个教程。这仅仅是一个实验的结果,延迟如何维持,以及对该平台的一些见解。享受吧!FINISHED
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)或者 我的个人博客 https://blog.qife122.com/
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/28 17:28:25

Java多线程:synchronized方法独占锁的秘密

文章目录Java多线程:synchronized方法独占锁的秘密?什么是synchronized?synchronized背后的独占锁机制1. 独占锁的定义2. 锁的粒度3. 锁的获取与释放独占锁的优缺点优点缺点案例分析:synchronized方法的常见问题例子代码&#xff…

作者头像 李华
网站建设 2026/2/28 11:12:13

Z-Image-Turbo_UI界面能否商用?许可证说明解读

Z-Image-Turbo_UI界面能否商用?许可证说明解读 Z-Image-Turbo_UI 是一个轻量、开箱即用的浏览器图形界面,专为快速调用 Z-Image Turbo 系列图像生成模型而设计。它不依赖复杂环境配置,只需一行命令即可启动,通过 http://localhos…

作者头像 李华
网站建设 2026/3/1 11:53:38

GPEN保姆级教程:如何用AI修复Stable Diffusion生成的脸部扭曲

GPEN保姆级教程:如何用AI修复Stable Diffusion生成的脸部扭曲 你是不是也遇到过这样的尴尬时刻——花半小时调提示词、选模型、等渲染,终于用 Stable Diffusion 生成了一张构图惊艳、光影绝美的角色图,结果放大一看:眼睛一大一小…

作者头像 李华
网站建设 2026/2/28 2:33:35

GPEN能修复侧脸和遮挡人脸吗?实测结果来了

GPEN能修复侧脸和遮挡人脸吗?实测结果来了 很多人第一次听说GPEN,是被它“修复1927年索尔维会议老照片”刷屏的震撼效果吸引来的。但真正用起来才发现:那些惊艳案例几乎全是正脸、高清轮廓、光照均匀的图像。那么问题来了——日常随手拍的侧…

作者头像 李华
网站建设 2026/2/28 21:19:51

基于SpringBoot+Vue的知识产权管理系统设计与实现(源码+lw+部署文档+讲解等)

课题介绍 在知识产权保护日益受到重视的当下,企业和个人对专利、商标、版权的管理需求愈发迫切,传统人工管理模式存在效率低下、数据杂乱、到期提醒不及时、查询不便等问题,难以满足现代化知识产权管理的精准化、高效化需求。为此&#xff0c…

作者头像 李华