Flask Windows 服务化 6 小时强制重启实战: 上次 NSSM 救 11 天后 PRO 又死了
结果 9/19 用户反馈 "PRO 登录页打不开了", 我一查:PRO 进程死了, watchdog bat 文件也没了, schtasks 任务也丢了。
11 天稳定运行的假象, 是 watchdog bat 早就被某次 Windows Defender 清扫时干掉了, 我又没察觉。9/23 我做了一件事: 不信任任何"自动"机制, 加了 6 小时强制重启兜底。三层守护: bat loop 死了秒拉起 + schtasks 6 小时强制 restart + 你手动也能一键重启。
↓ 11 天稳定 (W9 文章里写的 "528 小时无故障")
9/19 PRO 静默死亡 (我没察觉)
↓ 用户反馈 + 排查
9/23 加 6 小时强制重启 + bat loop + 监控告警
一、上次以为搞定了, 其实没
9/7 那个下午我花 3.5 小时死磕 NSSM, 最后用 schtasks + watchdog bat 救场。写完 W9 文章的时候我还挺得意:"528 小时无故障"。
结果 9/19 周日下午, 有用户邮件反馈 PRO 登录页打不开:
主题: PRO 登录不上
内容: 你好, https://www.baccpc.com:8000/login 这个页从昨天开始就打不开,
一直转圈。我是 VIP 会员, 帮我看一下。
我 RDP 登上去一查:
netstat -an | findstr ":8000"
# 什么都没输出
Get-Process python
# 也没输出
PRO Flask 进程死了, 而且死了至少 24 小时。PHD 还活着 (9/23 早上还能用), 但 PRO 没了。
我立刻检查 D:\phd824 和 D:\20260516\vb_bendi_v24 看 bat 文件还在不在:
Test-Path D:\phd824\run_phd_loop.bat
False
Test-Path D:\20260516\vb_bendi_v24\run_pro_loop.bat
False
两个 bat 都没了。watchdog bat 在 9/19 ~ 9/23 之间被人或系统清掉了, schtasks 任务虽然还在, 但执行的目标 bat 路径找不到, 所以服务死了也没人拉。
二、为什么 watchdog 救场不靠谱
W9 那套方案的逻辑是: Python 死了 → bat 检测到进程退出 → bat loop 回到 :restart → 杀所有 python → 重启 Python。
听起来完美, 但前提是 bat 自己活着。以下 3 种情况它会失效:
- bat 文件被删了: Windows Defender / 第三方杀毒 / 磁盘清理 / 手动误删
- bat 进程被杀: 杀软把 bat 当可疑脚本扫掉, 或者 cmd.exe 自身被回收
- schtasks 任务失效: 任务被禁用、删除、或者找不到 bat 路径
任何一种发生, 整套守护就失效。9/19 我遇到的是 1 (文件被清)。
三、6 小时强制重启: 不信任任何"自动"
9/23 我重新设计: 不依赖任何 bat 文件持续运行, 直接让操作系统层做定时 kill + 重启。
思路很简单:
- 第 1 层 (秒级): bat loop, 进程死了立即拉起 (跟 W9 一样, 但 bat 本身改放到桌面不容易被清)
- 第 2 层 (小时级): schtasks 6 小时强制 taskkill python.exe, 然后由第 1 层 bat 拉起新的 Python
- 第 3 层 (天级): 服务器重启 (每周/不定期) → Task Scheduler AtStartup 自动跑 bat
每一层独立工作, 任何一层失效, 其他两层兜底。
第 1 层: bat loop (桌面版本, 不放服务器)
我把 bat 放桌面, 不放 D:\ 根目录或 app 同级, 这样 Windows Defender 磁盘清理扫描 D:\ 时不会扫到:
桌面 `app.py -PRO.bat`:
@echo off
setlocal
title BaccAI PRO - 6h Auto Restart
cd /d D:\20260516\vb_bendi_v24
:loop
echo [%date% %time%] PRO watchdog started...
C:\Users\Administrator\AppData\Local\Programs\Python\Python38\python.exe app.py
goto :restart
:restart
echo [%date% %time%] PRO exited, killing all python and restarting in 10s...
timeout /t 10 /nobreak >nul
taskkill /F /IM python.exe /T 2>nul
timeout /t 5 /nobreak >nul
goto :loop
桌面 `app.py - PHD.bat` (同样逻辑, 路径换成 D:\phd824)。
第 2 层: schtasks 6 小时强制 taskkill
Windows Task Scheduler 不需要 bat 持续运行, 它自己就是个 Windows 服务, 由系统维护。我配了 2 个 6 小时定时任务, 每 6 小时强制杀所有 python.exe:
schtasks /Create /TN "BaccAI_PRO_6h_restart" /TR "taskkill /F /IM python.exe /T" /SC HOURLY /MO 6 /RL HIGHEST /RU SYSTEM /F
schtasks /Create /TN "BaccAI_PHD_6h_restart" /TR "taskkill /F /IM python.exe /T" /SC HOURLY /MO 6 /RL HIGHEST /RU SYSTEM /F
参数解释:
/TN= 任务名 (BaccAI_PRO_6h_restart / BaccAI_PHD_6h_restart)/TR= 触发时执行的命令 (taskkill /F /IM python.exe /T)/SC HOURLY /MO 6= 触发器: 每 6 小时一次/RL HIGHEST= 最高权限/RU SYSTEM= SYSTEM 账号 (跟 schtasks 服务本身一致, 不需要 bat)/F= 强制覆盖
关键设计: schtasks 本身不依赖任何 bat 文件, 它就是 Windows 服务, 永远不会被 Defender 清掉。taskkill 是 Windows 自带的 exe, 也不依赖 bat。
第 3 层: 服务器重启自动恢复
如果服务器本身重启 (Windows Update / 断电), 桌面的 bat 也会被关掉。我额外配了 2 个 ONSTART 任务, 开机 30 秒后自动跑桌面 bat:
schtasks /Create /TN "BaccAI_PRO_OnBoot" /TR "C:\Users\Administrator\Desktop\app.py -PRO.bat" /SC ONSTART /RL HIGHEST /RU SYSTEM /F
schtasks /Create /TN "BaccAI_PHD_OnBoot" /TR "C:\Users\Administrator\Desktop\app.py - PHD.bat" /SC ONSTART /RL HIGHEST /RU SYSTEM /F
但有个坑: ONSTART 跑 bat, bat 在 session 0 (系统服务会话) 里, 不会显示窗口, 也接受不到 stdin (如果要 Ctrl+C 杀进程会很麻烦)。不过我们不需要杀, 让它跑着就行。
四、6 小时是最佳平衡点
为什么是 6 小时, 不是 1 小时也不是 24 小时?
| 间隔 | 好处 | 坏处 | 适合谁 |
|---|---|---|---|
| 1 小时 | 死了秒拉, 几乎察觉不到 | 一天重启 24 次, 用户登录态/表单数据会丢 | 内部工具, 不在意用户体验 |
| 6 小时 | 一天 4 次, 体验可接受 | 短任务可能撞上 | ✅ 大部分 Web 服务, 推荐 |
| 24 小时 | 用户几乎感知不到 | 进程悄悄死掉, 24 小时没人拉 | 绝对不能中断的服务 (支付/医疗) |
我选了 6 小时。理由:
- 一天 4 次重启, 每次 15-20 秒窗口期 (taskkill + bat 等待 + Flask 启动 + 模型加载)
- 用户访问撞上重启窗口的概率: 假设每用户每天访问 10 分钟, 撞上 15 秒窗口 = 10/(6*60*60) ≈ 0.05%, 几乎为零
- 即使撞上, 刷新一下就好, 比"网站打不开等几小时"强 100 倍
五、可能踩的坑 + 解决
坑 1: bat 窗口被误关
我同事点桌面 bat 时偶尔误关 cmd 窗口, watchdog 失效。解决:
- bat 标题改成 "BaccAI PRO - DO NOT CLOSE" 之类, 让同事知道别关
- 或者写个 .vbs 启动 bat (隐藏 cmd 窗口), 但不推荐, 看不到实时输出排查困难
坑 2: schtasks 任务被禁用
Windows Update 或者某些系统优化工具会把 schtasks 任务 "禁用" (Disabled) 状态。检查:
schtasks /Query /TN "BaccAI_PRO_6h_restart"
看 "状态" 列, 不是 "Ready" 就是有问题。
坑 3: taskkill 杀掉其他 Python 进程
我服务器只跑这两个 Flask, 所以 taskkill python.exe 全杀安全。如果有其他 Python 程序, 改用 window title 过滤:
taskkill /F /FI "WINDOWTITLE eq BaccAI*" /T
只杀标题含 BaccAI 的窗口。
坑 4: 模型加载慢, 6 小时重启太频繁丢用户
PRO LSTM 模型加载要 5-10 秒, 加数据库连接池初始化总共 15-20 秒。如果用户正好在用 PRO 算预测, 重启会丢。
短期妥协: 6 小时已经够短, 用户撞上的概率低。
长期方案: 上 Nginx 反向代理, 滚动重启 (kill 一个 worker 起一个新 worker), zero-downtime。但成本高, 等 W10+ 流量再上。
六、完整启动卡 (D:\seo\START_COMMANDS.txt 更新版)
Step 1: 状态检查
netstat -an | findstr ":8443 :8000 :8080"
Get-Process python | Select Id, StartTime
schtasks /Query /TN "BaccAI_PRO_6h_restart"
schtasks /Query /TN "BaccAI_PHD_6h_restart"
Step 2: 启动 (4 种方式任选)
:: 方式 1: 双击桌面 bat (推荐, 启动 + watchdog 自动重启)
:: C:\Users\Administrator\Desktop\app.py -PRO.bat
:: C:\Users\Administrator\Desktop\app.py - PHD.bat
:: 方式 2: Start-Process 后台跑
Start-Process "C:\Users\Administrator\Desktop\app.py -PRO.bat"
Start-Process "C:\Users\Administrator\Desktop\app.py - PHD.bat"
:: 方式 3: 手动单次跑 (调试用)
cd /d D:\phd824
C:\Users\Administrator\AppData\Local\Programs\Python\Python38\python.exe app.py
Step 3: 紧急重启 (1 命令)
taskkill /F /IM python.exe /T
timeout /t 5 /nobreak
Start-Process "C:\Users\Administrator\Desktop\app.py -PRO.bat"
Start-Process "C:\Users\Administrator\Desktop\app.py - PHD.bat"
Step 4: 6 小时重启任务 (首次部署)
schtasks /Create /TN "BaccAI_PRO_6h_restart" /TR "taskkill /F /IM python.exe /T" /SC HOURLY /MO 6 /RL HIGHEST /RU SYSTEM /F
schtasks /Create /TN "BaccAI_PHD_6h_restart" /TR "taskkill /F /IM python.exe /T" /SC HOURLY /MO 6 /RL HIGHEST /RU SYSTEM /F
schtasks /Create /TN "BaccAI_PRO_OnBoot" /TR "C:\Users\Administrator\Desktop\app.py -PRO.bat" /SC ONSTART /RL HIGHEST /RU SYSTEM /F
schtasks /Create /TN "BaccAI_PHD_OnBoot" /TR "C:\Users\Administrator\Desktop\app.py - PHD.bat" /SC ONSTART /RL HIGHEST /RU SYSTEM /F
七、给 HCU 修复期的教训
9/7 写 W9 的时候我以为找到了终极方案, 9/23 就被现实打脸。这其实是 SEO 修复期的一个隐喻:
- 不要相信任何"自动": watchdog bat 看着自动, 但文件被清就完蛋。Google 的算法看着自动, 但 6/30 一次就把我打回原形。
- 多层冗余永远对: 6/30 我发了 47 篇 spam, Google 降权。9/23 我加了 6 小时强制重启, 把"自动"替换成"强制 + 多层"。站群内容也一样, 不要依赖单一来源 (论坛 / 转载 / AI 生成), 要 PGC + UGC + 转载 + 视频 多层组合。
- 看不见的失败最致命: 9/19 PRO 死了 24 小时我没察觉, 因为没有告警。最终方案我加了健康检查邮件告警 (W9 文章里有), 跟 W10 的 6 小时强制重启一起, 任何时候服务挂了我都会收到通知。