如何配置Gunicorn在优雅退出时执行Flask应用的save_db()函数?
解决Gunicorn优雅退出时执行save_db()的方法
原因分析
Flask开发服务器退出时会自动触发应用上下文清理流程,从而执行你注册的退出回调;但Gunicorn的worker进程有独立的生命周期管理逻辑,默认不会触发Flask的退出钩子,因此需要通过Gunicorn的自定义钩子来绑定save_db()的执行。
具体实现步骤
1. 在Flask应用代码中添加Gunicorn钩子处理
在你的flask/app.py中,新增Gunicorn钩子函数,利用其WORKER_EXIT事件触发保存操作:
from flask import Flask import gunicorn.signals import sys # 原有应用初始化代码 app = Flask(__name__) # ... 其他业务代码 ... def save_db(): # 你的内存数据同步到Redis的逻辑 pass # 绑定worker退出信号 def trigger_save_on_exit(server, worker): save_db() # 仅在Gunicorn运行环境下注册钩子 if 'gunicorn' in sys.modules: gunicorn.signals.signal(gunicorn.signals.WORKER_EXIT)(trigger_save_on_exit)
2. 配置Gunicorn启用优雅退出
启动Gunicorn时,指定优雅退出超时参数,确保worker有足够时间执行收尾操作:
gunicorn --workers=2 --timeout=30 --graceful-timeout=10 flask.app:app
--graceful-timeout=10:给worker预留10秒完成save_db等收尾任务- 使用
docker stop <容器名>触发退出时,Docker默认发送SIGTERM信号,会触发Gunicorn的优雅退出流程
3. 验证退出逻辑
启动容器后执行docker stop <容器名>,检查Redis中是否同步了内存数据库的数据,确认save_db()是否正常执行。
备选方案:使用atexit模块
如果Gunicorn钩子方式不生效,可尝试用atexit注册退出回调,注意多worker模式下每个worker退出都会执行一次,需确保save_db()支持Redis并发写入:
import atexit atexit.register(save_db)
内容的提问来源于stack exchange,提问作者creeper6530
相关产品推荐
相关产品推荐

