ber*_*ing 12 python parallel-processing fastapi uvicorn
我用 fastapi 和 uvicorn 进行了一项实验,但我不明白其结果。
关于代码
@app.get('/loadtest')
def root():
time.sleep(1)
return {'message': 'hello'}
Run Code Online (Sandbox Code Playgroud)
在 docker 中运行
CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
Run Code Online (Sandbox Code Playgroud)
我进行了以下测试:
ab -c 100 -n 1000 localhost/loadtest
Run Code Online (Sandbox Code Playgroud)
这给了我结果:
bersling-2:cas bersling$ ab -c 100 -n 1000 localhost/loadtest
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software: uvicorn
Server Hostname: localhost
Server Port: 80
Document Path: /loadtest
Document Length: 19 bytes
Concurrency Level: 100
Time taken for tests: 85.052 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 163000 bytes
HTML transferred: 19000 bytes
Requests per second: 11.76 [#/sec] (mean)
Time per request: 8505.191 [ms] (mean)
Time per request: 85.052 [ms] (mean, across all concurrent requests)
Transfer rate: 1.87 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.7 0 4
Processing: 1008 7964 1419.3 8010 9022
Waiting: 1004 7963 1419.3 8008 9020
Total: 1008 7965 1418.7 8010 9024
Percentage of the requests served within a certain time (ms)
50% 8010
66% 8016
75% 8988
80% 8989
90% 8993
95% 8998
98% 9003
99% 9006
100% 9024 (longest request)
Run Code Online (Sandbox Code Playgroud)
所以我们看到这大约需要 100 秒才能完成。但是,我预计需要 1000 秒,因为我假设请求需要按顺序处理,并且每个请求需要一秒钟。我假设了顺序队列,因为我认为 python 一次只能处理一个请求(在同步模式下),而且我不知道 uvicorn 会产生多个进程或线程。所以我不明白如何可能出现 100 秒的结果而不是 1000 秒的结果。有人可以解释一下吗?
ber*_*ing 14
引用文档:
当您使用普通 def 而不是异步 def 声明路径操作函数时,它会在等待的外部线程池中运行,而不是直接调用(因为它会阻塞服务器)。
或者引用github 讨论中的答案,该答案更容易阅读:
对于使用 def(不是 async def)定义的端点,FastAPI 将在线程池中运行它们,以避免阻塞服务器并允许并行处理多个请求。
这就提出了并发线程数量以及如何控制并发线程数量的问题。这个问题在这里得到解答。
为了方便再次引用:
fastAPI 基于用于控制 ThreadPoolExecutor 的 starlette ,但 starlette 现在使用 anyio ,所以我没有看到比你的提议更好的方法:
RunVar("_default_thread_limiter").set(CapacityLimiter(2))
| 归档时间: |
|
| 查看次数: |
11468 次 |
| 最近记录: |