【问题标题】:How to send a lot of simultaneous requests to FastAPI endpoint?如何向 FastAPI 端点发送大量同时请求?
【发布时间】:2021-10-30 05:54:14
【问题描述】:

使用像下面这样的“正常”协同程序,结果是首先打印所有请求,然后在大约 5 秒后打印所有响应:

import asyncio

async def request():
    print('request')
    await asyncio.sleep(5)
    print('response')

loop = asyncio.get_event_loop()

tasks = [
    loop.create_task(request())
    for i in range(30)
]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

我想在 FastApi 中复制相同的行为,所以我有这样的端点:

import asyncio

from fastapi import FastAPI

app = FastAPI()

@app.post("/")
async def root():
    print('request')
    await asyncio.sleep(5)
    return 'OK'

我用来自前端的多个请求来轰炸它,如下所示:

 const url = 'http://localhost:8000'
 const data = [1, 2, 3]
 const options = {
     method: 'POST',
     headers: new Headers({'content-type': 'application/json'}),
     body: JSON.stringify({data}),
     mode: 'no-cors',
 }

 for (let i=0; i<30; i++) {
     fetch(url, options)
 }

但是,在终端中我可以清楚地看到,FastAPI 一次只接受 6 个请求,为它们返回响应,然后再接受另外 6 个:

request
request
request
request
request
request
←[32mINFO←[0m:     127.0.0.1:63491 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:58337 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:50479 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:60499 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:56990 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:56107 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
request
request
request
request
request
request
←[32mINFO←[0m:     127.0.0.1:58337 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:63491 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:60499 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:56990 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:56107 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:50479 - "←[1mPOST / HTTP/1.1←[0m" ←[32m200 OK←[0m

等等

这是因为某些 FastAPI/uvicorn 设置或限制吗?

数量是否可以增加,是否合理?

【问题讨论】:

  • 您的应用运行情况如何?它只是通过一个简单的uvicorn 命令还是您使用pre-made FastAPI docker images 之一?
  • 我通过uvicorn main:app --reload运行它

标签: asynchronous fastapi uvicorn


【解决方案1】:

您在浏览器中执行此操作,因此您实际上达到了浏览器中的并行请求限制。它与 API 本身无关。如果您想测试 API 的性能,请使用专门为此设计的工具 - 例如 siegehttperfab 或类似工具。

来自the answer documenting the current parallel request limits in browsers

Firefox 3+: 6
...
Edge:       6
Chrome:     6

【讨论】:

  • 嗯,谢谢!我检查了我的浏览器限制(Chrome),确实是 6 个请求。假设无法控制浏览器设置,您将如何解决这样的限制?我的猜测是将此类批量请求所需的数据从浏览器传递到某个后端服务,然后该服务将查询我的 API。
  • 有一些技巧可以解决这个问题 - 例如配置多个指向同一服务的主机(例如,使用通配符主机),因为限制是每个来源的。第二种方法是在一个请求中批量处理所有内容,并在您的接收视图中将其拆分;性能应该比 n 请求更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-25
  • 1970-01-01
  • 2017-04-21
  • 2020-05-12
  • 2019-09-29
相关资源
最近更新 更多