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

如何在Flask(uWSGI)服务中捕获SIGTERM/SIGINT信号?

解决uWSGI运行Flask服务时捕获K8S发送的SIGTERM/SIGINT信号问题

错误原因

你遇到的ValueError: Signal must be registered on the main thread,是因为Python的signal模块要求信号处理函数必须在主线程中注册,而你的类中信号注册逻辑大概率在子线程执行;同时uWSGI本身有独立的信号处理机制,直接混用Python原生signal容易引发冲突。

解决方案

1. 移至主线程注册Python原生信号处理函数

把信号注册逻辑放到程序启动的主线程代码中,不要放在Flask类的子线程方法或视图函数内。比如在Flask应用初始化的最外层执行:

import signal
from flask import Flask

app = Flask(__name__)

def exit_gracefully(signum, frame):
    # 编写你的清理操作:关闭数据库连接、保存运行状态、通知依赖服务等
    app.logger.info("Received SIGTERM/SIGINT, starting graceful shutdown")
    # 手动触发Flask服务关闭(如果适用)
    shutdown_func = getattr(request.environ.get('werkzeug.server.shutdown'), '__call__', None)
    if shutdown_func:
        shutdown_func()

# uWSGI加载应用时,这段代码在主线程执行
if __name__ != '__main__':
    signal.signal(signal.SIGINT, exit_gracefully)
    signal.signal(signal.SIGTERM, exit_gracefully)

@app.route('/')
def index():
    return "Hello World"

2. 使用uWSGI内置信号钩子(推荐)

uWSGI提供了专门的信号注册API,能更好地适配其运行时,避免线程问题。你可以直接在Python代码中绑定信号:

import uwsgi
from flask import Flask

app = Flask(__name__)

def cleanup():
    # 执行优雅终止逻辑
    app.logger.info("Executing cleanup on SIGTERM/SIGINT")
    # 示例:关闭数据库连接
    # db_session.close()

# 在主线程注册uWSGI信号
# SIGTERM对应信号编号15,SIGINT对应编号2
uwsgi.register_signal(15, "", cleanup)
uwsgi.register_signal(2, "", cleanup)
# 启用信号监听
uwsgi.add_signal(15, "")
uwsgi.add_signal(2, "")

@app.route('/')
def index():
    return "Hello World"

也可以在uWSGI配置文件(如uwsgi.ini)中通过钩子绑定:

[uwsgi]
module = app:app
master = true
processes = 1
threads = 4
# 绑定SIGTERM到清理脚本
hook-signal = SIGTERM:python /path/to/cleanup.py
# 绑定SIGINT到清理脚本
hook-signal = SIGINT:python /path/to/cleanup.py

3. 配合K8S优雅终止配置

在K8S Pod配置中设置合理的优雅终止时间,确保清理逻辑有足够执行时间:

apiVersion: v1
kind: Pod
metadata:
  name: flask-app
spec:
  containers:
  - name: flask
    image: your-flask-image
    terminationGracePeriodSeconds: 60  # 根据清理逻辑耗时调整

注意事项

  • 无论使用哪种方式,信号注册逻辑必须在主线程执行,子线程无法完成信号注册。
  • SIGKILL信号无法被捕获,需保证清理逻辑能在K8S优雅终止时间内完成,避免被强制杀死。
  • 若使用uWSGI master进程模式,确保信号能正确传递到工作进程,或直接在master进程中处理信号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 07:19:58