性能比拼: 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 计算优化实例 部署 Prometheus 、Grafana 和用于生成负载的客户端。

计算优化实例的硬件与通用实例相同,但 内存更少,每小时价格便宜 $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 等其他基准测试感兴趣,可以查看我的频道。

谢谢观看,我们下次见!

相关推荐
高级程序源5 小时前
django校园寻物通失物招领平台32261-计算机课程设计、毕业设计
vue.js·python·mysql·小程序·django·flask·课程设计
WeiXin_DZbishe5 小时前
基于springboot宠物领养系统-计算机毕设 附源码【课程设计】94217
vue.js·spring boot·python·django·php·课程设计
kimnoic6 小时前
Python数据库学习心得:SQLite、MySQL、PostgreSQL优缺点
开发语言·python
snhna6 小时前
向量数据库深度实战:从 HNSW 到 pgvector、Milvus 选型与 RAG 落地
数据库·人工智能·python·postgresql·milvus
必须得开心呀7 小时前
python编写带界面的软件,需要安装哪些插件
开发语言·python
Wx-bishekaifayuan7 小时前
express皖美特色农产品网售系统53118-计算机课程设计、毕业设计
人工智能·spring boot·后端·python·课程设计·express·旅游
青少儿编程课堂7 小时前
迪杰斯特拉(Dijkstra)算法:单源最短路与赛场路线规划
c++·python·算法·bfs·信息学竞赛
计算机编程指导师7 小时前
【计算机毕设推荐】基于Hadoop+Spark的公共交通运营数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·计算机·数据分析·spark·交通
Wx-bishekaifayuan7 小时前
springboot汉中旅游服务平台41442-计算机课程设计、毕业设计
spring boot·后端·python·django·课程设计·express·旅游
WeiXin_DZbishe8 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计