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

FastAPI异步接口在Gunicorn+Uvicorn Docker环境下同步运行问题排查

异步FastAPI应用在Gunicorn+Uvicorn部署下无法异步运行的修复方案

问题背景

采用Gunicorn作为进程管理器、Uvicorn Worker运行异步FastAPI应用,部署在Docker容器中,但含await asyncio.sleep(10)的异步接口表现为串行处理,而非预期的并发执行。开发环境直接用Uvicorn运行时异步功能正常。

相关代码与配置

FastAPI端点代码

@router.get("/info", status_code=status.HTTP_200_OK, response_model=InfoReturn)
async def info():
    main_logger.info("BEFORE INFO")
    await asyncio.sleep(10)
    main_logger.info("AFTER INFO")
    return {
        "version": __VERSION__,
        "description": "Application for conquering the world !"
    }

Dockerfile配置

FROM python:3.11.2-alpine3.17

RUN mkdir -p /opt/app && mkdir -p /etc/app
VOLUME ["/etc/app"]
WORKDIR /opt/app

COPY requirements.txt /opt/app

RUN set -e; \
    apk update && apk add --no-cache --virtual .build-deps \
        gcc \
        libc-dev \
        musl-dev \
        linux-headers \
        python3-dev \
        libffi-dev \
        openssl-dev \
    ; \
    pip install --upgrade pip; \
    pip install --ignore-installed --no-cache-dir -r requirements.txt; \
    pip install "psycopg[binary,pool]"; \
    apk add vim; \
    apk --purge del .build-deps;

COPY ["." , "/opt/app"]

CMD ["gunicorn", "run:app", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]

问题现象

容器中运行时,并发请求/info接口会串行处理,日志输出如下:

2023-03-14 13:37:38|testing_api|INFO|BEFORE INFO
2023-03-14 13:47:38|testing_api|INFO|AFTER INFO
2023-03-14 13:47:38|testing_api|INFO|BEFORE INFO
2023-03-14 13:57:38|testing_api|INFO|AFTER INFO

预期的异步并发日志应为:

2023-03-14 13:37:38|testing_api|INFO|BEFORE INFO
2023-03-14 13:37:38|testing_api|INFO|BEFORE INFO
2023-03-14 13:47:38|testing_api|INFO|AFTER INFO
2023-03-14 13:47:38|testing_api|INFO|AFTER INFO

修复方案

1. 修正测试方式(最常见原因)

浏览器会对同域名、同路径的GET请求进行排队限制(如Chrome默认限制同域名并发连接数为6,且重复GET请求会串行发送),导致接口看似串行处理。改用无并发限制的工具测试:

  • 终端用curl并发发送:
    curl http://localhost:8000/info & curl http://localhost:8000/info
    
  • 使用Postman批量请求功能,或多个独立窗口同时发送请求
  • 用Python脚本并发测试:
    import asyncio
    import aiohttp
    
    async def fetch(session, url):
        async with session.get(url) as response:
            return await response.json()
    
    async def main():
        async with aiohttp.ClientSession() as session:
            tasks = [fetch(session, "http://localhost:8000/info") for _ in range(2)]
            results = await asyncio.gather(*tasks)
            print(results)
    
    if __name__ == "__main__":
        asyncio.run(main())
    

2. 确认依赖版本兼容性

确保requirements.txt包含兼容版本的依赖:

fastapi>=0.95.0
uvicorn>=0.22.0
gunicorn>=20.1.0

旧版本Uvicorn Worker可能存在异步处理Bug,更新到稳定版本可解决问题。

3. 调整Gunicorn Worker配置

  • 确保使用正确的异步Worker类:uvicorn.workers.UvicornWorker(禁止使用同步Worker)
  • 可增加每个Worker的并发连接数(Uvicorn默认每个Worker处理100个并发连接),修改Dockerfile的CMD命令:
    CMD ["gunicorn", "run:app", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000", "--worker-connections", "1000"]
    

4. 确认应用的异步设置

检查run.py中FastAPI实例创建是否正确,确保未意外使用同步模式:

from fastapi import FastAPI
app = FastAPI()  # 默认支持异步,无需额外配置

# 导入路由
from app.routes import router
app.include_router(router)

验证

按上述方案调整后,重新构建Docker镜像并运行,用正确的测试工具发送并发请求,即可看到日志输出符合预期的异步并发模式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:54:56