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

如何让Flask在终止前等待所有请求处理完成?

实现Flask优雅停机:等待当前请求完成后终止

默认用flask run启动的开发服务器,收到终止信号(比如Ctrl+C触发的SIGINT)时会直接退出,不会等待正在处理的请求(比如大文件下载)完成。要实现优雅停机,可通过以下两种方案解决:

方案1:基于信号捕获的开发环境实现

通过捕获终止信号,标记应用进入维护模式拦截新请求,同时等待现有请求处理完成后再关闭服务器,代码实现如下:

from flask import Flask, abort
import signal
import time
from werkzeug.serving import run_simple

app = Flask(__name__)

# 标记是否允许接收新请求
allow_new_requests = True

@app.route("/download")
def download_large_file():
    # 模拟大文件下载的耗时逻辑
    print("开始处理大文件下载请求...")
    time.sleep(10)
    return "大文件内容".encode("utf-8")

@app.before_request
def block_new_requests():
    """拦截新请求,返回维护提示"""
    global allow_new_requests
    if not allow_new_requests:
        abort(503, description="服务器正在停机维护,请稍后再试")

def handle_shutdown(signum, frame):
    global allow_new_requests
    print("\n收到停机信号,启动优雅停机流程...")
    # 停止接收新请求
    allow_new_requests = False
    print("已停止接收新请求,等待现有请求处理完成...")
    # 根据业务最长请求耗时调整等待时长
    time.sleep(15)
    print("现有请求处理完毕,服务器退出")
    exit(0)

if __name__ == "__main__":
    # 捕获Ctrl+C触发的SIGINT信号
    signal.signal(signal.SIGINT, handle_shutdown)
    # 用Werkzeug的run_simple启动,和flask run行为一致
    run_simple("localhost", 5000, app, threaded=True)

核心逻辑

  1. 用signal模块捕获终止信号,触发优雅停机流程
  2. 通过全局变量+before_request钩子拦截新请求,返回503状态码
  3. 设置等待时长,确保正在处理的请求有足够时间完成

方案2:生产环境用支持优雅停机的服务器(推荐)

生产环境不建议使用Flask自带的开发服务器,推荐用Gunicorn这类原生支持优雅停机的WSGI服务器:

  • 启动命令:gunicorn --workers=2 --timeout=120 app:app
  • 触发优雅停机:执行kill -TERM <Gunicorn主进程ID>,或直接按Ctrl+C,Gunicorn会自动等待worker处理完当前请求后再退出

关键配置参数

  • --timeout:设置单个请求的最长处理时长,避免无限等待
  • --graceful-timeout:自定义优雅停机的等待时长(默认30秒)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:27:12