You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI+Uvicorn多请求并行处理问题咨询及解决方案

FastAPI多进程运行相关问题

背景与代码

我是Python开发新手,但有.NET开发背景。编写了一个简单的FastAPI应用:

from fastapi import FastAPI
import time
import logging
import asyncio
import random

app = FastAPI()
r = random.randint(1, 100)
logging.basicConfig(level="INFO", format='%(levelname)s | %(asctime)s | %(name)s | %(message)s')
logging.info(f"Starting app {r}")

@app.get("/")
async def long_operation():
    logging.info(f"Starting long operation {r}")
    await asyncio.sleep(1)
    time.sleep(4) # 我知道这会阻塞且端点标记为async,但我的代码中确实存在阻塞请求
    return r

使用如下命令启动应用:

uvicorn "main:app" --workers 4

启动后应用创建了4个进程实例,日志如下:

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started parent process [22112]
INFO | 2023-05-11 12:32:43,544 | root | Starting app 17
INFO:     Started server process [10180]  
INFO:     Waiting for application startup.
INFO:     Application startup complete.   
INFO | 2023-05-11 12:32:43,579 | root | Starting app 58
INFO:     Started server process [29592]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO | 2023-05-11 12:32:43,587 | root | Starting app 12
INFO:     Started server process [7296]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO | 2023-05-11 12:32:43,605 | root | Starting app 29
INFO:     Started server process [15208]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

打开3个浏览器标签页并行发送请求,日志如下:

INFO | 2023-05-11 12:32:50,770 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK
INFO | 2023-05-11 12:32:55,774 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK
INFO | 2023-05-11 12:33:00,772 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK
INFO | 2023-05-11 12:33:05,770 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK
INFO | 2023-05-11 12:33:10,790 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK
INFO | 2023-05-11 12:33:15,779 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK
INFO | 2023-05-11 12:33:20,799 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK
INFO | 2023-05-11 12:33:25,814 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK
INFO | 2023-05-11 12:33:30,856 | root | Starting long operation 29
INFO:     127.0.0.1:55031 - "GET / HTTP/1.1" 200 OK

观察结果

  • 仅1个进程在处理请求,其余进程未参与(多次测试均如此);
  • 已成功创建4个不同的实例。

疑问

  1. 为何仅一个进程工作,其余进程不处理请求?
  2. 能否实现内存缓存?
  3. 能否用单个进程并行处理一定数量的请求?
  4. 该现象是否与我在Windows系统上测试有关?

更新+解决方案

核心问题是def/async def的行为(容易混淆)。原本尝试通过多进程解决线程阻塞问题,但测试时仅一个进程工作,原因是使用单个浏览器的多个标签页测试。改用JMeter测试后,所有进程均正常被使用。

但多进程并非最优解,更好的方式是解除单进程中的线程阻塞:

  • 起初使用asyncio.loop.run_in_executor方案,因为依赖的外部库只有同步IO函数;
  • 后来找到了该函数的异步版本,最终通过使用正确的异步库解决问题。

感谢大家的帮助。


内容的提问来源于stack exchange,提问作者Anubis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:50:48