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

Docker+FastAPI启动与关闭异常:Ctrl+C触发asyncio取消错误排查

关于Uvicorn+FastAPI关闭时出现asyncio.exceptions.CancelledError的问题解析

问题背景

我在排查Uvicorn+FastAPI应用无法接收SIGTERM、Docker Compose需10秒后发送SIGKILL终止的问题时,编写了极简示例应用测试,按下Ctrl+C关闭应用时出现asyncio.exceptions.CancelledError异常,想了解该异常原因,是否是代码、Uvicorn或FastAPI存在问题?


相关文件与输出

示例代码

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

Dockerfile

# Use an official Python runtime as the parent image
FROM python:3.11-slim

# Set the working directory
WORKDIR /app

# Copy the requirements.txt files to install dependencies
COPY requirements.txt /app/

# Install dependencies
RUN pip install -r requirements.txt

# FastAPI app
COPY . /app/
WORKDIR /app/
CMD ["uvicorn", "fastsample:app", "--host", "0.0.0.0", "--port", "8888"]

控制台输出(已翻译异常信息)

docker run -p 8888:8888 uvidemo
INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8888 (Press CTRL+C to quit)
INFO:     172.17.0.1:41148 - "GET / HTTP/1.1" 200 OK
INFO:     172.17.0.1:41148 - "GET / HTTP/1.1" 200 OK
INFO:     172.17.0.1:41148 - "GET / HTTP/1.1" 200 OK
INFO:     172.17.0.1:41148 - "GET / HTTP/1.1" 200 OK
INFO:     172.17.0.1:41148 - "GET / HTTP/1.1" 200 OK
^CINFO:     Shutting down
INFO:     Finished server process [1]
ERROR:    回溯(最近的调用最后):
  文件 "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 686, in lifespan
    await receive()
  文件 "/usr/local/lib/python3.11/site-packages/uvicorn/lifespan/on.py", line 137, in receive
    return await self.receive_queue.get()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  文件 "/usr/local/lib/python3.11/asyncio/queues.py", line 158, in get
    await getter
asyncio.exceptions.CancelledError

异常原因解析

这个CancelledError是正常的异步任务终止信号,并非代码、Uvicorn或FastAPI的问题,具体原因:

  • 按下Ctrl+C时,系统向进程发送SIGINT信号,Uvicorn收到后启动优雅关闭流程,主动取消所有运行中的异步任务(包括框架内部的生命周期管理协程)。
  • 异常来自Starlette(FastAPI依赖的底层框架)的lifespan协程:应用关闭阶段,该协程仍在等待接收生命周期事件,Uvicorn取消了这个等待操作,触发标准的asyncio.CancelledError。
  • 该异常是异步编程中任务被取消时的标准行为,Uvicorn本身会处理此异常,部分版本会打印异常信息,但不影响应用正常关闭。

关于SIGTERM接收问题的补充

你最初排查的Docker Compose需10秒发送SIGKILL的问题,与这个CancelledError无关,常见解决方向:

  • 确保Uvicorn以PID 1运行:Docker默认仅向PID 1进程发送信号,若进程PID不是1则无法接收SIGTERM。可修改Dockerfile的CMD为exec形式:
    CMD ["exec", "uvicorn", "fastsample:app", "--host", "0.0.0.0", "--port", "8888"]
    
  • 调整优雅关闭超时:添加--timeout-graceful-shutdown参数,给应用足够时间处理完现有请求再退出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:55:11