Rust主流框架性能比拼: Actix vs Axum vs Rocket

本内容是对知名性能评测博主 Anton Putra Actix (Rust) vs Axum (Rust) vs Rocket (Rust): Performance Benchmark in Kubernetes 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准

在以下中,我们将比较 Rust 生态中最受欢迎的几个框架。我会将三个应用程序部署到 Kubernetes,并使用 Prometheus 和 Grafana 进行监控。

我们将测量每个应用程序的 CPU 使用率,相对于 Kubernetes 部署中设定的限制。同时,我们也会测量内存使用情况,相对于其设定的限制。当然,你也可以测量实际数值,比如应用程序使用了多少 MB 或 GB 的内存,但基于使用率百分比阈值设定告警会更加简单。

此外,我们还会测量每个应用程序可以处理的请求数量,最重要的是客户端延迟---即处理每个请求所需的时间。我们将使用 p99 百分位 进行测量(我在另一个视频里详细解释了百分位的概念)。

我们还会测量应用程序的 可用性 ,计算方式为:成功请求数 ÷ 总请求数 × 100 。最后,由于这些应用程序运行在 Kubernetes 中,我们还需要测量 CPU 限制节流(CPU Throttling)

为了进行测试,我在 AWS 上创建了一个 生产级的 EKS 集群 。如果你感兴趣,我的频道里有完整的教程,教你如何搭建。我使用了最新的 m7a.8xlarge 实例,每个应用程序只获取一部分可用的 CPU 和内存,其余资源则用于其他基础设施和用于生成负载的客户端。


代码概览

每个应用程序都包含一个 /api/devices 端点,返回 JSON 格式的数据给客户端。你可以在我的 GitHub 公开仓库 中找到源代码。如果你有任何改进建议,欢迎提供意见或提交 Pull Request!如果某些更改确实带来了影响,我会更新视频并展示新的测试结果。

所有应用程序都使用了 Rust 的 标准优化 ,并以 release 选项构建。此外,我使用了 distroless Debian 镜像来构建 Docker 镜像。

如果你感兴趣,以下是最终的镜像大小。我们可以使用 UPX 进一步压缩,就像我对 Go 语言的镜像所做的那样,使其减少到 3-4 MB。不过,在这次测试中,镜像大小并不会影响性能表现,因此不作进一步优化。


测试过程

现在,我们将所有三个应用程序部署到 Kubernetes ,并让它们在 空闲状态 下运行 15 分钟 。你会发现,各个框架的 CPU 使用率 存在一些轻微差异,但非常小,几乎可以忽略不计。另一方面,内存使用情况 也很小,但你可能会注意到不同的行为模式:

  • Axum 的内存使用较为平稳;
  • ActixRocket 则会出现 短暂的内存尖峰

接下来,我们开始 测试 ,并部署 Kubernetes Jobs 来生成负载。整个测试持续了约 1.5 小时 ,但我在视频中将其缩短至几分钟。最后,我们会查看整个测试过程中的各项 监控图表

我们将 每 3 分钟 增加 1000 个请求/秒 ,持续增加,直到这些应用程序开始 无法承受负载


初步结果

在测试初期,负载较小,此时最重要的指标是 客户端延迟。你会发现:

  • Rocket 框架 的延迟 从一开始就最高 ,并且 CPU 使用率 也高于其他框架;
  • 然而,其内存使用保持稳定 ,因为 Rust 没有垃圾回收(Garbage Collection),并且测试时只返回了 硬编码的 JSON 数据,并未占用太多内存。
  • Actix 和 AxumCPU 和延迟方面表现相似

此时,测试负载仅为最大可承受负载的 20% ,因此我们可以得出结论:在低负载下,Actix 和 Axum 的性能几乎相同 。但在实际应用中,我们希望测试所有可能的场景,包括让应用程序承受 极限负载

为了确保测试结果的稳定性,我在不同的 EC2 实例上多次运行了测试,结果始终一致。


增加负载后的结果

当负载达到 30%(仍属于轻负载)时,我们开始看到明显的区别:

  • Actix 的延迟最低 ,其次是 AxumRocket 依然是最慢的
  • 随着负载增加,Actix 和 Axum 之间的差距逐渐扩大 ,不仅表现在 延迟 ,还体现在 CPU 使用率 上(尽管差距较小,但可以观察到)。

此时,平均请求处理时间仅为 100-200 微秒 (注意,不是毫秒)。我将 客户端超时时间 设为 200 毫秒 ,当请求超时时,客户端会收到 408 状态码 ,这会影响应用的 可用性

需要注意的是,应用程序崩溃的原因并不一定是 CPU 或内存达到 100% 使用率 。应用程序可能会因 响应过慢、无法处理请求 而导致客户端超时。此外,Kubernetes 的健康检查(Readiness Probes) 也可能超时,导致应用被移出 服务池(Service Pool)

在本次测试中,我们认为 可用性下降 并且 应用无法在 200 毫秒内处理请求 ,即视为 测试失败


推至极限负载

在负载增加到 27,000 请求/秒 时,所有应用程序都开始 出现失败 。因此,我们可以认为 最大可承受的负载大约为 26,000 请求/秒 ,之后响应时间会 急剧恶化,应用将被移出服务池。

尽管三者的 延迟表现不同 ,但它们 几乎在同一时间开始崩溃。不过,在整个过程中:

  • Actix 的延迟始终是最低的

数据分析

接下来,我们查看各项图表:

  1. 每秒请求数(Requests Per Second)
  1. 内存使用情况(Memory Usage)
    • 当应用开始变慢,需要存储更多 待处理请求 时,内存使用出现尖峰
  1. CPU 使用率(CPU Usage)
    • Rocket 使用的 CPU 最高Actix 的 CPU 使用率最低
  1. 可用性(Availability)
    • 虽然所有应用几乎在同一时间开始失败,但 Actix 的可用性更高 ,即:它在 更低的延迟下处理了更多请求
    • 下次测试时,我会 减少负载递增的幅度,看看哪一个框架能处理更多请求。
  1. 客户端延迟(Client Latency)
    • 在测试后期,我们看到了一些延迟 尖峰,但它们并不是最重要的部分。
    • 在应用程序仍然健康的阶段,Actix 的延迟最低,并且是最后一个失败的框架。
  1. CPU 限制节流(CPU Throttling)

    • 没有任何应用程序达到 100% CPU 使用率 ,因此没有发生 CPU 限制节流
相关推荐
来自星星的坤1 小时前
SpringBoot 与 Vue3 实现前后端互联全解析
后端·ajax·前端框架·vue·springboot
AUGENSTERN_dc1 小时前
RaabitMQ 快速入门
java·后端·rabbitmq
烛阴2 小时前
零基础必看!Express 项目 .env 配置,开发、测试、生产环境轻松搞定!
javascript·后端·express
燃星cro2 小时前
参照Spring Boot后端框架实现序列化工具类
java·spring boot·后端
追逐时光者5 小时前
C#/.NET/.NET Core拾遗补漏合集(25年4月更新)
后端·.net
FG.5 小时前
GO语言入门
开发语言·后端·golang
转转技术团队6 小时前
加Log就卡?不加Log就瞎?”——这个插件治好了我的精神
java·后端
谦行6 小时前
前端视角 Java Web 入门手册 5.5:真实世界 Web 开发——控制反转与 @Autowired
java·后端
uhakadotcom6 小时前
PyTorch 2.0:最全入门指南,轻松理解新特性和实用案例
后端·面试·github
bnnnnnnnn6 小时前
前端实现多服务器文件 自动同步宝塔定时任务 + 同步工具 + 企业微信告警(实战详解)
前端·javascript·后端