发布于 2026-01-06 1 阅读
0

使用 Appwrite 0.13 将您的无服务器函数速度提升至全新高度 🙋 什么是云函数?💻 架构概述 📦 依赖管理 ⏳ 基准测试 💪 工程挑战 🌅 结论

使用 Appwrite 0.13,让您的无服务器函数运行速度更上一层楼。

🙋 什么是云函数?

💻 架构概述

📦 依赖管理

⏳ 基准测试

💪 工程挑战

🌅 结论

🙋 什么是云函数?

云函数是一种扩展云服务提供商服务的方式,它可以执行您的代码并添加以前不存在的功能。许多服务都具备这种功能!例如 AWS Lambda、Google Cloud Functions 和 Vercel Functions。

亚马逊在 2014 年推出 AWS Lambda 时率先进入云函数领域,四年后谷歌紧随其后,于 2018 年向所有人开放了 Google Cloud Functions。这一切促成了今天的 Appwrite,它推出了第二代 Appwrite Functions,其执行模型得到了显著改进。

💻 架构概述

那么,与之前的版本相比,有哪些变化呢?正如前面提到的,我们的执行模型已经过全面重新设计,以速度为核心。

我们首先需要了解原有的执行模型是如何运作的,才能理解这些变化。

0.12 执行模型流程图

上图展示了原始函数执行模型的工作原理。每次执行都会执行此操作。因此,本质上,每次执行都会启动一个新的 Docker 容器。这种流程耗时较长,并且会给宿主机带来相当大的压力。

现在将其与 0.13 版本的模型进行比较:
0.13 执行模型流程图

更新后的模型要复杂得多(尽管这里展示的是一个经过大幅简化的示意图),它不再每次执行都启动一个新的运行时环境。不仅如此,每个运行时环境现在都内置了一个 Web 服务器来处理执行。我们现在使用 HTTP 请求而不是命令行执行,从而大大提高了执行速度。使用这种执行方式确实会给用户带来一些变化。例如,用户必须输入脚本的文件名,而不是完整的命令。他们现在还需要导出函数。更多详情请参阅我们的函数文档

📦 依赖管理

还记得以前需要手动将依赖项打包到函数代码中吗?现在不用了!Appwrite 0.13 为函数引入了构建阶段,它可以自动安装所需的所有依赖项。构建阶段还会构建已编译的运行时环境,使其可以执行。某些语言可能需要特定的步骤,因此我们建议您查看更新后的函数文档

⏳ 基准测试

得益于我们全新的执行模型,函数速度现在比以前快了 10 倍以上!我们甚至首次在 Appwrite 中引入了对编译型语言的支持,包括 Rust 和改进后的 Swift 运行时,带来了令人惊叹的执行速度。不妨让我们来看看一些可靠的基准测试数据,比较一下 0.12 和 0.13 版本在执行时间和规模上的差异。

我们的第一个测试是使用 NodeJS 17.0 的异步执行模型实现一个简单的“Hello World!”响应。我们使用异步方法来比较这两个版本,因为 0.12 不支持同步函数,直接比较异步和同步是不公平的。我们使用k6作为基准测试工具,所有脚本都在本地设备上运行。为了正确地进行基准测试,我们准备了一个代理,它可以冻结请求并统计在特定时间段内有多少请求到达该代理。流程如下:

  1. 创建 Appwrite 函数标签并激活它
  2. 启动一个启用请求冻结功能的代理服务器。
  3. 运行 k6 基准测试 60 秒
  4. 解冻代理服务器
  5. 等待所有操作完成

在这种配置下,k6 将在 60 秒内创建尽可能多的执行实例。在此期间,只有第一个执行实例会启动,但只有在代理服务器冻结后才会完成。这种冻结机制确保在测试 Appwrite 可以创建多少个执行实例时,不会因执行实例而占用过多 CPU 资源。

一分钟后,k6 基准测试完成,我们解冻代理服务器,从而恢复执行队列。我们等待所有执行完成,同时跟踪代理服务器上的计时数据。

这次基准测试的结果令人惊叹!Appwrite 0.12 生成了20700 个执行,而 0.13 版本则生成了20824 个执行。由于我们在这个版本中没有重构创建过程,因此 0.6% 的提升幅度在意料之中。但从函数执行时间的对比来看,性能的提升之大令人震惊。Appwrite 0.12 的执行速度为每分钟360 次,而 Appwrite 0.13 的执行速度更是惊人地达到了每分钟5820 次!

应用程序写入功能基准测试

我们进行的第二个测试是在实际场景中使用 Appwrite,以查看平均执行时间的改进情况。为此,我们在六个不同的运行时环境中准备了相同的脚本。我们使用了一个将电话号码转换为国家/地区代码的示例脚本,该脚本来自Open Runtimes 示例 GitHub 存储库。该脚本运行了以下命令:

  1. 从 Appwrite Locale SDK 获取国家/地区电话前缀数据库
  2. 验证请求负载
  3. 在前缀中查找匹配项
  4. 返回国家信息

为了对这些功能进行基准测试,我们使用了相同的 k6 技术,但这次流程更简单:

  1. 创建功能部署并激活它
  2. 运行基准测试 60 秒
  3. 等待执行完成
  4. 计算平均执行时间

我们在 0.12 和 0.13 版本中,分别使用六种不同的运行时环境(语言)运行了这些脚本,结果令人震惊!最令人惊讶的结果是使用 Dart 语言,我们竟然在不到一毫秒的时间内运行了该脚本!

说到这里,我们先来说说 Dart。Dart 是一种编译型语言,这意味着编译后的结果是二进制代码。这使得它的执行速度极快,因为所有代码都以 0 和 1 的形式准备就绪,可以直接在服务器上运行。由于 0.12 版本对编译型语言的支持不佳,我们函数的平均执行时间达到了 1895 毫秒。在 0.13 版本中运行相同的脚本时,我们的预期很高,但平均执行时间竟然骤降至0.98 毫秒,这着实让我们震惊不已!

Dart 执行时间对比图

我们继续来看另一种常用语言——NodeJS。同样的函数,之前在 0.12 秒内需要 325 毫秒才能执行完毕,现在在 0.13 秒内仅需1.45 毫秒!这个结果让我非常惊讶,因为我没想到解释型语言能有如此出色的性能。

NodeJS 执行时间对比图

为了进一步比较 NodeJS,我们又对比了Deno,其 0.13 版本的结果与 NodeJS 类似,平均耗时约为3 毫秒。差距略小,因为该函数在 0.12 版本中仅耗时145 毫秒

Deno 执行时间对比图

我们继续使用PHP进行测试,PHP 是一种广为人知的语言,互联网上有很多网站都在使用它。在 0.12 版本中,平均延迟为 106 毫秒;而在 0.13 版本中,平均延迟降至7 毫秒

PHP 执行时间对比图

我们继续使用PythonRuby进行测试,结果相似。在 0.12 版本中,Python 的执行时间为 254 毫秒,而 Ruby 的平均执行时间为 358 毫秒。令人难以置信的是,在 0.13 版本中,Python 的执行时间仅为11 毫秒,Ruby 的速度也略有提升,为9.5 毫秒

Python 执行时间对比图

Ruby 执行时间对比图

正如您所看到的,此次版本发布后执行速度显著提高,我们期待看到使用 Appwrite 的开发者将如何利用这些新功能。

💪 工程挑战

为了实现同步执行并优先考虑速度,我们决定放弃大多数工作进程使用的基于任务的系统,转而为 Appwrite 创建一个名为执行器 (executor) 的新组件。执行器将负责所有编排和执行职责,并从函数工作进程中移除 Docker 套接字。执行器是一个使用SwooleUtopia构建的 HTTP 服务器,并使用各种 Appwrite 库与数据库进行交互。

最初的挑战之一是创建一个编排库,以便将来如果需要,可以轻松切换到其他编排工具,例如 Kubernetes 或 Podman。这一改变将使我们能够使用其他编排工具,例如 Kubernetes 或 Podman,并允许用户使用他们喜欢的编排工具运行 Appwrite。目前,我们为该库提供了两个适配器:Docker CLI 和 Docker API;不过,我们计划随着时间的推移不断扩展适配器的选择范围。

下一个挑战是,Swoole 的协程 cURL 钩子存在一些 bug,而我们正是利用这个钩子与 Docker API 版本的编排库进行通信。这些 bug 迫使我们使用 Docker CLI 适配器,这导致了更长的等待时间和速率限制问题,进而造成了高负载下的不稳定。

我们提出了一种解决方案,即引入类似队列的系统来使用 Docker。这项改动会略微降低运行时的启动速度,但实际执行始终使用 cURL 请求,因此执行时间不会受到此改动的负面影响。

🌅 结论

通过这些改进,我们希望 Appwrite 能提供更多功能,帮助您构建梦想中的应用程序,同时又不牺牲速度和灵活性。我们都非常期待看到大家利用这些新功能和函数执行速度的提升,创造出怎样的作品。

我们鼓励您加入我们的Discord 服务器,在那里您可以随时了解 Appwrite 的最新动态,并在需要时获得 Appwrite 开发人员的帮助!

文章来源:https://dev.to/appwrite/take-your-serverless-functions-to-new-speeds-with-appwrite-013-5868