部署于IIS+wFastCGI的Flask应用随机重启问题及定时API调用咨询
问题原因
在IIS+wFastCGI环境下,你的Flask应用运行在wFastCGI进程池中,IIS默认会根据一系列规则自动回收worker进程:
- 进程空闲超过默认20分钟
- 进程运行时间达到默认1740分钟(29小时)的定期回收周期
- 进程占用内存超过设定阈值
- 应用池配置的其他回收触发条件
每次进程被回收重启,Flask应用都会重新初始化,你的API类也会被再次实例化,对应的刷新线程也就被多次启动。哪怕开启了Always On,也仅能避免空闲回收,无法阻止其他回收规则触发的进程重启。
另外你贴出的代码本身存在语法问题:
__init少了一个下划线,正确写法是__init__(self)self.session等属性的代码缩进错误,应放在__init__方法内部- 启动线程时需传入
target=self.refresh_data,否则会丢失实例上下文
处理定时API调用的建议
1. 彻底分离定时任务与Flask应用(最优方案)
把数据刷新的定时逻辑从Flask进程中抽离,做成独立程序,通过Windows服务或任务计划程序运行:
- 编写单独的Python脚本,负责定时调用API更新数据,并将数据存入共享缓存(如Redis、本地JSON文件、SQLite数据库)
- Flask应用仅负责从缓存读取数据返回给前端,完全不处理定时刷新逻辑
这种方式下,无论IIS如何重启Flask进程,都不会影响定时任务的运行,也不会出现多线程重复刷新的问题。
2. 调整IIS应用池回收策略(缓解方案)
如果暂时不想拆分应用,可调整应用池设置减少进程重启频率:
- 打开IIS管理器,找到对应应用池→高级设置
- 将**空闲超时(分钟)**设为0,关闭空闲回收
- 将**定期回收时间间隔(分钟)**调大(或设为0关闭定期回收)
- 调高私有内存限制(KB)和虚拟内存限制(KB),避免因内存占用触发回收
但这种方法只能减少重启次数,无法完全避免——IIS仍可能因服务器更新、配置变更等原因回收进程。
3. 用进程间共享状态控制重复执行(临时方案)
如果必须将定时任务放在Flask进程内,可通过文件锁或共享内存控制仅一个线程运行:
- 刷新线程启动前,检查特定锁文件是否存在,存在则不启动;启动后创建锁文件,退出时删除
- 或使用Redis分布式锁,确保同一时间只有一个刷新线程在运行
这种方法能避免多进程重复执行刷新,但可靠性远不如拆分方案。
4. 修复代码语法错误
先修正代码基础问题,避免运行时出错:
""" The API class gets initialized on webserver start """ import requests import threading import time class API: def __init__(self): # 修复下划线缺失问题 self.API_KEY = 'xxx-xxx' self.BASE_URL = 'https://xxxxxxxx.com/3' self.HEADER = { 'X-Api-Key': f'{self.API_KEY}', 'Accept': 'application/json' } # 修复缩进,将属性初始化放入__init__方法内 self.session = requests.session() self.session.headers.update(self.HEADER) self.data = {} self.refresh_time = 900 # 刷新间隔(秒) # 修复线程目标参数,传入实例方法并设置为守护线程 threading.Thread(target=self.refresh_data, daemon=True).start() def refresh_data(self): # 改为类方法,添加self参数 while True: self._refresh() # 实际API调用与数据更新逻辑 time.sleep(self.refresh_time) def _refresh(self): # 此处编写调用API并更新self.data的逻辑 pass
内容的提问来源于stack exchange,提问作者LiiVion
相关产品推荐
相关产品推荐

