性能比拼: Go标准库 vs Python FastAPI

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

在本视频中,我们将对比 FastAPI (Python 生态中最快的 Web 框架之一)和 Golang 标准库的性能。


第一轮测试

为了建立基准,我们的第一轮测试仅测试框架本身的性能:

  • 每个应用程序都会返回 硬编码对象 ,并以 JSON 格式 响应客户端。

  • 我们将测量以下关键指标:

    • 99% 分位数的延迟
    • 每秒请求数(Requests per Second, RPS)
    • CPU 使用率
    • 内存使用率
    • 错误率(可用性)
    • CPU 限流(CPU Throttling)

由于我们会在 AWS 上的生产级 Kubernetes 集群 部署这些应用程序,因此测试环境尽可能贴近真实生产环境。


第二轮测试

第二轮测试更加有趣:

  • 当应用程序收到 POST 请求 时:
    • 解析请求体。
    • 生成 UUID 和时间戳。
    • 将记录插入 关系型数据库(PostgreSQL)
    • (新增)使用缓存系统:在插入数据库后,将对象(包括数据库生成的 ID)存入缓存。

本次测试首次加入了缓存 ,我选择了 Memcached ,因为它的性能更高。但如果你感兴趣,可以在另外的视频中看到它与 Redis 的对比。

为了更细致地分析性能,我使用 Prometheus 监测每个应用的关键操作,例如 数据库插入缓存存取。此外,我们还会测量:

  • PostgreSQL 和 Memcached 的 CPU 使用率
  • 每个应用程序创建的数据库连接池大小

测试环境

所有测试都在 AWS 运行:

  • Memcached 部署在 m7a.xlarge 实例
  • PostgreSQL 部署在 2xlarge 专用 EC2 实例
  • EKS 集群
    • 第一组节点 :使用 m7a.large 通用实例 运行应用程序。
    • 第二组节点 :使用 Graviton 计算优化实例 部署 PrometheusGrafana 和用于生成负载的客户端。

计算优化实例的硬件与通用实例相同,但 内存更少,每小时价格便宜 $0.10。由于测试不需要太多内存,所以我尽可能优化成本。


第一轮测试

开始执行第一轮测试

这轮测试没有任何依赖项,甚至没有业务逻辑,仅仅是返回硬编码的数据给客户端。

从一开始,你就能看到 性能上的巨大差异

  • 客户端测量的延迟 :FastAPI的延迟至少是Go 应用程序 的 两倍
  • CPU 使用率
    • 在过去的测试中,Python 应用的 CPU 使用率通常远高于其他语言
    • FastAPI 在 13,000 RPS 左右开始跟不上,无法处理更多请求。
    • 由于 CPU 资源耗尽,Kubernetes 开始对 FastAPI 进行限流,导致其延迟大幅上升。
  • Go 应用在 25,000 RPS 时,FastAPI 彻底崩溃
    • Python 服务器过载,导致 可用性降至 0
    • 客户端请求要么超时,要么返回 500 错误
    • 在 FastAPI 彻底崩溃期间,客户端不会收到响应,因此延迟图表上会出现空白

从性能表现来看,FastAPI 的表现类似于 Django,甚至只稍微好一点

如果你有优化方案,欢迎提交 Pull Request ,我会重新测试。但到目前为止,我对 FastAPI 的表现感到失望,本来期望它的性能会更好。

接下来,我让测试继续运行,直到 Go 应用达到极限

  • Go 应用的 RPS 在 60,000 - 62,000 之间,和我之前的基准测试非常一致。
  • Kubernetes 运行 Go 应用 时,建议限制 Go 用户线程数,这样 Kubernetes 就不会对其进行过多的限流。

第一轮测试结果

1. 每秒请求数(RPS)

  • FastAPI 最高达到 13,000 RPS
  • Go 最高达到 62,000 RPS

2. 客户端延迟

  • FastAPI 失败时,延迟图表会出现空白
  • Go 的整体延迟远低于 FastAPI

3. CPU 使用率

  • FastAPI 在前 10-15 分钟内就达到 CPU 上限,并开始性能下降

4. 可用性

  • 计算方式:成功请求数 / 总请求数
  • FastAPI 崩溃后,可用性直接降为 0

5. 内存使用

  • Go 在崩溃前,内存使用量会激增

6. CPU 限流

  • FastAPI 的 CPU 限流现象更严重 ,因为它很快就耗尽了 CPU 资源

第二轮测试

在这轮测试中,我们首次引入缓存

  • 每当应用收到请求:
    • 解析请求体。
    • 插入 PostgreSQL
    • 将数据存入 Memcached

为什么选 Memcached 而不是 Redis?

  • Memcached 更高效,可以使用更小的实例,节省基础设施成本。

第二轮测试结果

第一次运行测试时

  • FastAPI 仅使用 60% 的 CPU(2 个 Worker 进程)
  • 由于大量 I/O 操作 (数据库 & 缓存),我增加 Worker 进程至 4 ,CPU 使用率提升至 80%

1. RPS

  • FastAPI 仅能处理 800 RPS,表现远远落后于 Go。

2. 数据库 & 缓存操作

  • Go 的数据库和缓存操作延迟明显更低
  • POST 请求的整体延迟也更低

3. 资源限制

  • FastAPI 在 10-15 分钟内达到极限 ,而 Go 需要运行 1 小时才能达到极限

4. PostgreSQL 和 Memcached 监控

  • 测量 PostgreSQL 和 Memcached 的 CPU 使用率
  • 应用程序数据库连接池大小
    • 每个应用的连接池限制为 500
    • 数据库最大连接数增加到 1000+

5. Go 在 35,000 RPS 时失败

  • 原因 :我忘了增加 Linux 服务器的 文件描述符限制(file descriptor limit)。

  • 若优化文件描述符,Go 还能处理更多请求 ,但FastAPI 远远不在同一水平线上,所以我没必要重新测试。


最终结果

打开测试图表:

  • 每秒请求数
  • POST 请求延迟

Go最后的延迟峰值是由于文件描述符造成的

  • 数据库延迟
  • Memcached 延迟
  • 应用程序 CPU 使用率
  • PostgreSQL 和 Memcached CPU 使用率
  • 连接池大小
  • 内存使用情况

如果你有优化方案,欢迎查看视频描述中的源代码链接
我原本期待 FastAPI 的性能更好,希望有人能优化它。

如果你对 Rust vs Go 等其他基准测试感兴趣,可以查看我的频道。

谢谢观看,我们下次见!

相关推荐
mqiqe15 分钟前
Spring MVC 页面跳转方案与区别
python·spring·mvc
小白的高手之路20 分钟前
torch.nn.Conv2d介绍——Pytorch中的二维卷积层
人工智能·pytorch·python·深度学习·神经网络·机器学习·cnn
船长@Quant23 分钟前
PyTorch量化进阶教程:第五章 Transformer 在量化交易中的应用
pytorch·python·深度学习·transformer·量化交易·sklearn·ta-lab
冰蓝蓝35 分钟前
什么是 实例化
python
returnShitBoy1 小时前
Go语言中的defer关键字有什么作用?
开发语言·后端·golang
天天进步20151 小时前
Python项目-基于Flask的个人博客系统设计与实现(2)
开发语言·python·flask
RadNIkMan2 小时前
Python学习(二)操作列表
网络·python·学习
SoFlu软件机器人2 小时前
Go/Rust 疯狂蚕食 Java 市场?老牌语言的 AI 化自救之路
java·golang·rust
飞川撸码2 小时前
【LeetCode 热题100】240:搜索二维矩阵 II(详细解析)(Go语言版)
leetcode·矩阵·golang
半盏茶香2 小时前
启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——堆的应用之堆排、Top-K问题
java·开发语言·数据结构·c++·python·算法·链表