如何向FastAPI端点发送大量并发请求?为何FastAPI仅能同时处理6个请求?
问题原因与解决方案
首先明确:你看到的每批仅处理6个请求的现象,主要是浏览器的同源请求限制导致的,其次才可能涉及uvicorn的配置。咱们一步步拆解来看:
1. 最可能的原因:浏览器的并发请求限制
现代浏览器(Chrome、Firefox等)都有个默认规则:对同一个域名的并发HTTP/1.1请求数最多是6个。你的前端用fetch循环发30个请求,浏览器会自动把这些请求排队,先发送6个,等某一个请求完成后再补下一个,所以终端才会看到一批6个处理完再处理下一批——这和FastAPI、uvicorn本身没关系,是浏览器为了避免服务器过载做的限制。
2. 次要可能:Uvicorn的默认配置
如果用非浏览器的工具压测还是有类似问题,那才是uvicorn的配置限制。Uvicorn默认是单worker进程,虽然单个异步worker理论上能处理大量IO密集型请求,但如果你的系统资源有限,或者有其他配置(比如limit-concurrency),也会影响并发能力。
如何实现预期的并发行为
想要复现你最初asyncio示例里“一次性处理所有请求、5秒后一起返回”的效果,分两步调整:
第一步:绕过浏览器限制,用后端工具压测
不要用浏览器发起请求,改用异步HTTP客户端写压测脚本,比如用httpx:
import asyncio import httpx async def send_single_request(client): await client.post("http://localhost:8000/", json={"data": [1,2,3]}) async def main(): async with httpx.AsyncClient() as client: # 一次性创建30个异步任务 tasks = [send_single_request(client) for _ in range(30)] await asyncio.gather(*tasks) if __name__ == "__main__": asyncio.run(main())
运行这个脚本,你会看到终端瞬间打印所有request,5秒后一次性返回所有响应,完全符合你的预期。
第二步:调整Uvicorn配置提升服务并发能力
如果你的服务需要支撑更高的并发量,可以调整uvicorn的启动参数:
- 增加worker进程数:利用多核CPU,比如4核CPU就开4个worker:
uvicorn your_app_file:app --workers 4 - 设置单worker的并发上限:如果单worker的并发不够,可以通过
limit-concurrency参数调整(比如设为200):uvicorn your_app_file:app --limit-concurrency 200 - 可选:限制单个worker的最大请求数:防止内存泄漏,比如每个worker处理10000个请求后重启:
uvicorn your_app_file:app --workers 4 --limit-max-requests 10000
提高并发数的合理性
是否要提高并发数,得看你的业务场景和系统资源:
- 完全合理的场景:如果你的服务是IO密集型(比如频繁调用外部API、数据库查询、文件读写),增加并发数能充分利用CPU资源,大幅提升吞吐量——这正是FastAPI+uvicorn异步架构的设计初衷。
- 需要注意的坑:
- 别盲目堆并发数,否则会耗尽CPU、内存或网络资源,反而让服务崩溃。建议逐步调整,配合压测找到最优值。
- 如果是CPU密集型服务(比如大量计算),异步架构的优势不大,此时应该增加worker数(对应CPU核数),而不是单worker的并发数。
- 还要考虑下游承受力:如果你的服务要调用数据库或其他外部服务,过高的并发可能压垮下游,得配合限流、降级等策略。
内容的提问来源于stack exchange,提问作者barciewicz
相关产品推荐
相关产品推荐

