哪个无服务器边缘平台拥有最快的 Git 部署速度?
边缘部署越来越普遍,提供无服务器边缘计算的服务也越来越多。其中最重要的因素之一是部署速度,因为上下文切换和等待代码构建和部署可能会阻碍开发的势头、状态流以及开发人员的生产力。
那么,哪个无服务器边缘计算平台的部署速度最快呢?
我决定为以下每个无服务器边缘提供商设置一个微型应用程序,并将其连接到 GitHub Actions,这样您就不必亲自动手了。(相信我,您不希望为了一篇博文而花一个下午的时间来折腾 IAM 角色和权限。)
- Cloudflare Workers
- Vercel
- Fly.io
- Deno
AWS Lambda @ Edge*
* 我尝试使用 GitHub Actions 以编程方式更新 Cloudfront 分发触发器,以便使用新部署的 Lambda 函数。如果有人对此有技巧,请告诉我们。
(所有微型应用程序和相应的 GitHub Action 脚本都可以在这里查看。)
结果
其他边缘提供商的部署时间都在一分钟左右,而Deno Deploy 的速度快得多。其他提供商的部署时间主要花在配置机器、安装工具和运行构建上。Deploy 只需上传代码,并在 Deploy 本身中完成任何 HTML 生成或客户端 JavaScript 的捆绑。
诚然,我们在一个狭窄的标准(部署速度)上评估这些无服务器边缘平台,因为开发人员使用它们肯定还有其他原因。尽管如此,对于 CI/CD 流程而言,部署速度对于开发人员的生产力和敏捷性至关重要。
下面,我们将深入探讨每个平台的设置过程,并展示从推送到 GitHub 到看到效果生效之间的时间的细分。
但首先……我们如何一致地衡量 CI/CD Git 部署的速度?
方法论
为了确保我们在 CI/CD 部署速度方面进行苹果与苹果的比较,我们将重点关注**从main
Git 分支更新到网站上检测到更改之间的时间**,原因如下:
- **在 Git 分支
main
上推送**: 尽管 Git 不是运行 CI/CD 服务器的唯一方法,但所有这些供应商都集成了 Git 或 GitHub Action,因此我们将使用它来消除 CI/CD 服务器带来的任何差异。这也是从这里开始计时的好地方,因为main
上的更新通常标志着 CI/CD 构建过程的开始。 - **网站上检测到更改**: 由于供应商需要通过其边缘网络传播更新,因此在 GitHub Actions(或 CI/CD 服务器)上的构建完成后,更改才会反映到网站上,这之间会有延迟。
为了始终如一地衡量时间,我们使用了一个脚本来启动计时器,反复 ping 网站,直到检测到更改,然后输出时间差。所有测试都将在我的机器和我的互联网上进行,消除了结果中的这些可变因素。
第一步是更新边缘函数,使其包含字符串phrase_to_search_for
。
然后,我们运行以下命令:
$ deno task ping {app_url} {phrase_to_search_for}
该命令执行三件事:
- 使用
git
更新并推送到main
分支 - 运行
/tasks/ping.ts
,该脚本启动计时器并 ping 公开边缘函数地址app_url
,直到检测到字符串phrase_to_search_for
- 输出时间差
ping.ts
脚本为:
/*
* Usage
*
* deno task ping [app_url] [phrase_to_search_for_in_next_deployment]
* e.g. deno task ping https://nextjs-vercel-demo-gules.vercel.app/ hazelthenuttypug
*/
const url = Deno.args[0];
const keyPhrase = Deno.args[1];
// Start timestamp.
const startTimeStamp = Date.now();
console.log("");
console.log("");
console.log(`Starting the timer...`);
let noChangeDetected = true;
while (noChangeDetected) {
const res = await fetch(url);
const body = await res.text();
if (body.includes(keyPhrase)) {
noChangeDetected = false;
console.log(`${keyPhrase} detected on website...`);
}
}
// Calculate time difference.
const endTimeStamp = Date.now();
const differenceInTimeStamp = endTimeStamp - startTimeStamp;
console.log(`Total deployment time: ${differenceInTimeStamp / 1000}s`);
该脚本接受两个参数:
app_url
: 部署应用程序的公共可访问地址,以及phrase_to_search_for_in_next_deployment
: 更新应用程序中应该出现的字符串,该脚本将使用它来检测更改
例如,我将“hazelthenuttypug” 添加到 Vercel 函数并运行:
$ deno task ping https://nextjs-vercel-demo-gules.vercel.app/ hazelthenuttypug
让我们深入了解每个平台的结果。
Cloudflare Workers
Cloudflare Workers 是在边缘部署和执行代码的一种常用方法。
这个设置相当简单(感谢这个简短的指南)。点击他们界面上的几个按钮,设置 GitHub 仓库,然后添加cloudflare/wrangler-action
GitHub Action 以及必需的秘密令牌。在 10 分钟内,我能够通过推送到main
将我的函数更新到 Cloudflare Workers。
部署速度
让我们看看 Git 部署需要多长时间。
deno task --cwd cloudflare ping https://test_project.andyjiang.workers.dev/ hazelthenuttypug
Warning deno task is unstable and may drastically change in the future
Task ping git add . && git commit -am 'update' && git push origin main && deno run -A ../tasks/ping.ts "https://test_project.andyjiang.workers.dev/" "hazelthenuttypug"
[main bd9760a] update
1 file changed, 1 insertion(+), 1 deletion(-)
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 339 bytes | 339.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:lambtron/cloudflare-workers-git-deploy-demo.git
41efcdf..bd9760a main -> main
Starting the timer...
hazelthenuttypug detected on website...
Total deployment time: 60.202s
我尝试了几次,结果都在一分钟左右。深入研究这个数字,发现 GitHub Action 本身非常快,只有 22 秒(“发布” 13 秒,使用 Docker 容器执行wrangler publish
)
剩余的 40 秒左右是更改在 Cloudflare Workers 网络上生效所需的时间。
Fly.io
在使用 AWS Lambda 和 Cloudflare Workers 之后,Fly.io 的设置非常简单。我按照这个快速入门 的步骤进行操作,安装了flyctl
,并在几分钟内从命令行完成了部署。
通过 GitHub Actions 设置 CI/CD 也相当简单。我从这个 Fly.io 持续部署快速入门 中复制粘贴了.github/workflows/main.yml
,将FLY_API_TOKEN
添加到我的 GitHub 秘密,它在第一次尝试时就成功了。
总的来说,这是一个流畅而轻松的设置体验。
部署速度
现在让我们测试一下部署速度。
deno task --cwd fly.io ping https://falling-bush-2722.fly.dev/ hazelthenuttypug
Warning deno task is unstable and may drastically change in the future
Task ping git add . && git commit -am 'update' && git push origin main && deno run -A ../tasks/ping.ts "https://falling-bush-2722.fly.dev/" "hazelthenuttypug"
[main 1b2adda] update
1 file changed, 1 insertion(+), 1 deletion(-)
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 312 bytes | 312.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:lambtron/fly-io-git-deploy-demo.git
bc0ab29..1b2adda main -> main
Starting the timer...
hazelthenuttypug detected on website...
Total deployment time: 57.321s
57.3 秒比部署到 Cloudflare Workers 快,但优势并不明显。但是,从内部看,我们发现大部分时间(约 55 秒)花在flyctl deploy
上,该命令会构建 Docker 镜像并将其推送到 fly.io 注册表
Vercel
Vercel 的边缘网络 是另一个流行的边缘部署服务。请注意,Vercel 上的大多数部署不在其边缘网络上。为了部署到其边缘,需要几个额外的步骤。
在这里,获得一个常规的项目设置很简单。有几种方法可以快速入门,例如克隆模板、导入 git 仓库等。我克隆了一个模板,然后他们在下一页让我直接创建一个 GitHub 仓库。最棒的是,CI/CD 会自动与项目一起设置 - 无需创建 .github
工作流程。
接下来,我必须按照这份详细指南,在我的项目中创建一个 Vercel 边缘函数 作为路由。这仅仅意味着在 /pages/api/hello.ts
中包含额外的配置代码,因此总体而言并不太难。
如果我有更多耐心,我相信有一种方法可以使边缘函数返回 HTML,而不是 JSON。
无论哪种方式,这都是使用内置 CI/CD 在边缘设置应用程序最简单、最容易的方法。
部署速度
2023/01/23 更新:感谢Ethan-Arrowood 提交的 PR,简化了此示例以仅部署边缘函数(而不是整个 NextJS 网站)。
ping.ts
脚本检测到的 20 次测试的更新的中位部署速度为 12.575 秒。
检查 Vercel 中随机部署之一的部署日志
- 克隆 GitHub 仓库:1.224 秒
- 安装和解析依赖项:1.65 秒
- 完成构建:4 秒
- 部署输出:1 秒
- 上传构建缓存:387 毫秒
不确定为什么部署日志中输出的秒数没有一致的有效数字,但总和大约为 10 秒。
将仅边缘函数部署到 Vercel 很简单,速度也很快,大约为 10 秒。
更新结束
让我们测试一下它的部署速度。
deno task --cwd vercel ping https://nextjs-vercel-demo-gules.vercel.app/api/hello/ hazelthenuttypug
Warning deno task is unstable and may drastically change in the future
Task ping git add . && git commit -am 'update' && git push origin main && deno run -A ../tasks/ping.ts "https://nextjs-vercel-demo-gules.vercel.app/api/hello/" "hazelthenuttypug"
[main 5d4b286] update
2 files changed, 1 insertion(+), 5187 deletions(-)
delete mode 100644 package-lock.json
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 462 bytes | 462.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:lambtron/vercel-edge-git-deploy-demo.git
5699276..5d4b286 main -> main
Starting the timer...
hazelthenuttypug detected on website...
Total deployment time: 54.041s
查看 Vercel 仪表盘,我们看到仅构建过程就花费了 46 秒
可以进一步分解为
- 克隆 GitHub 仓库:4.3 秒
- 运行
vercel build
(解析、获取、链接、构建依赖项):22.25 秒 - 运行
next build
(编译、生成静态页面、完成页面优化):11.12 秒 - 填充和上传构建缓存:1.3 秒
Deno
Deno Deploy 是我们的多租户分布式 JavaScript 隔离云。
设置非常容易 - 虽然不像 Vercel 那样简单。我们仍然需要离开 Deno Deploy 网站才能创建一个 GitHub 仓库。但在创建 GitHub 仓库后,只需进行一些下拉选择,我们就可以将项目与 Deno Deploy 连接起来。
除了将 Deno Deploy 连接到 GitHub 的简单性之外,Deno Deploy 只需要一个入口点文件。在此示例中,我们的整个仓库只有一个 main.ts
文件。
部署速度
让我们测试一下部署速度。
deno task --cwd deno ping https://deno-git-deploy-demo.deno.dev/ hazelthenuttypug
Warning deno task is unstable and may drastically change in the future
Task ping git add . && git commit -am 'update' && git push origin main && deno run -A ../tasks/ping.ts "https://deno-git-deploy-demo.deno.dev/" "hazelthenuttypug"
[main bb0233e] update
1 file changed, 1 insertion(+), 1 deletion(-)
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 273 bytes | 273.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:lambtron/deno-git-deploy-demo.git
ef7e42a..bb0233e main -> main
Starting the timer...
hazelthenuttypug detected on website...
Total deployment time: 3.493s
通过 git 在 3.5 秒内在全球范围内部署,速度快得惊人。这种神奇的部署速度归功于我们在构建 Deno Deploy 背后的架构决策:我们没有启动 VM 或 Docker 容器,Deploy 使用了 V8 隔离,这使我们能够以更少的开销安全地运行不受信任的代码。
下一步是什么?
我们希望使 Web 开发变得有趣和简单 - 这包括难以置信的快速、神奇的部署体验。最小的上下文切换意味着成为更高效的开发人员。