FastAPI、Gin 和 Spring Boot 谁更快,结果跟我想的完全不一样
我一直以为自己对“哪个框架最快”有清晰的认识。FastAPI 用了两年,Go 的 Gin 在我的印象里应该能碾压 Python,Spring Boot 则在“企业级稳定”上占优。出于好奇,我在三个框架里构建了完全相同的 API,然后向每个服务发起了每分钟 100 万请求的测试。
结果出来的时候,我盯着屏幕看了好几遍——它们颠覆了我对“高性能”的全部认知。
测试怎么做的
我搭建了一个真实的 API 场景:从 PostgreSQL 里取 100 行数据,序列化成 JSON,返回。不走 Hello World 这种“空跑”捷径。
- 硬件:AWS c6i.2xlarge(8 核,16GB RAM)
- 数据库:PostgreSQL 15 + pgbouncer
- 压测工具:wrk,2 线程,1000 连接,持续 30 秒
- 核心指标:吞吐量(req/s)、P50/P99 延迟、内存稳定性
结果:所有人都没想到的赢家
Spring Boot + 原生 JDBC 以 7,886 req/s 碾压全场。 不是 Gin,不是 FastAPI——是那个被很多人认为“太重”的 Spring Boot。
FastAPI 优化后跑了 4,831 req/s,Gin 在数据库场景下只有 3,100 req/s。更让我意外的是延迟稳定性:Spring Boot 平均延迟只有 1.37ms,而且非常稳定;FastAPI 在 P95 下会飙到 120ms;Gin 的延迟则从 13ms 到 200ms 剧烈波动。
但故事的转折来了:在纯 I/O 场景(调用外部慢速 API)中,FastAPI 的异步优势开始显现。而在纯 CPU 计算(比如算斐波那契数列)时,Gin 以 8,923 req/s 对 FastAPI 的 227 req/s 形成了 40 倍的碾压。
结论很直接:“快”没有绝对答案,完全取决于你的瓶颈在哪。
为什么 Spring Boot 赢了?
Spring Boot 的杀手锏是 JDBC 连接池 + JIT 编译。JVM 在预热之后会将热点代码编译成高效的机器码,加上 HikariCP 的数据库连接池管理,让它在数据库密集型的场景下表现得异常出色。这次测试中我用的是原生 JDBC,如果换成 JPA/Hibernate,性能会直接掉到只有 844 req/s——差了整整 9 倍。
FastAPI 的陷阱与正确打开方式
FastAPI 是这三个里最容易写出“慢代码”的框架。
用 psycopg2 同步驱动,吞吐量能从 4,800 掉到 827 req/s。不加 Gunicorn 多进程,Uvicorn 单进程跑不满多核 CPU。正确做法是用 asyncpg 异步驱动,配合 Gunicorn 启动多个 Uvicorn worker,加上 orjson 替代默认的 JSON 序列化器——这一套组合拳下来,FastAPI 才能跑到接近 5,000 req/s 的水平。
Gin 的优势不在数据库
Gin 的路由性能确实是三个里最快的,但一旦加入了数据库 I/O,优势就被大幅压缩了。Go 的并发模型让它在处理大量并发 goroutine 时游刃有余,内存占用极低——但它改变不了数据库查询本身的耗时。禁用 gin.Default() 中的日志中间件、使用 pgx 原生驱动、配置好连接池,这些都是必须做的功课。
挑框架,不如先挑瓶颈
- 数据库是主要瓶颈时,Spring Boot + JDBC 是目前最好的选择
- 外部 I/O 是瓶颈时,FastAPI 的异步生态能让开发效率大幅提升
- CPU 计算是瓶颈时,Gin 的编译型语言优势会完全显现
三个框架都能在各自擅长的场景下跑得很好,区别在于你需要知道自己的场景属于哪一种。我曾经以为“快”是一个绝对属性,但现在的结论更接近于:框架选型是取舍,不存在通用的最优解。
如果你现在正在选型,不妨先跑一个针对你自己业务场景的 benchmark——结果可能会让你重新思考。
更多推荐



所有评论(0)