# Gateway Watchdog 设计文档 **版本**: 1.0 **作者**: 庞统(副军师)🐦 **日期**: 2026-05-28 **状态**: 已实现 --- ## 1. 问题背景 zhipu GLM-5.1 在高峰期返回 **429 限流**("该模型当前访问量过大,请您稍后再试",errorCode=1305),导致: 1. Gateway 调用失败,`stopReason=error` 2. Session 进入 stalled 状态 3. stalled 后无法自动恢复,必须手动重启 Gateway 4. 所有 Agent 假死,直到人工介入 ### 历史记录 - 2026-05-26 09:00 CST — 429 导致假死 - 2026-05-28 ~10:00 CST — 429 导致假死,持续约 1 小时 - 累计 9 次 session.stalled 事件 ## 2. 双层防护 ### 2.1 第一层:跨 Provider Fallback(立即生效) **配置**: `~/.openclaw/openclaw.json` ```json { "model": { "primary": "zhipu/glm-5.1", "fallbacks": ["deepseek/deepseek-v4-pro"] } } ``` - zhipu 429 时自动切 deepseek(不同 provider,不会一起死) - deepseek-v4-pro 也是免费的,支持 1M 上下文 - Gateway 原生支持,无需额外代码 ### 2.2 第二层:Watchdog 自动重启(兜底) 即使 fallback 也失败(所有 provider 同时挂),watchdog 检测到连续 429 后自动重启 Gateway。 ## 3. Watchdog 设计 ### 3.1 检测原理 **数据源**: Gateway 的 session jsonl 日志 ``` ~/.openclaw/agents/{agent-id}/sessions/*.jsonl ``` **429 精确特征**: ```json { "message": { "stopReason": "error", "errorCode": "1305", "errorMessage": "429 该模型当前访问量过大,请您稍后再试" } } ``` **判定条件**(全部满足才算 429): 1. `stopReason === "error"` 2. `errorMessage` 包含 `"429"` 或 `errorCode` 为 `"1305"` **不会误判**: - 正常 stop(`stop=stop`、`stop=toolUse`)不算 - 其他 error(如 context overflow 的 errorCode 不同)不算 - `stopReason` 不是 `"error"` 的不算 ### 3.2 检测流程 ``` 每分钟执行 │ ├─ Gateway health check │ ├─ 失败 → 直接重启(可能 Gateway 进程已死) │ └─ 成功 → 继续 │ ├─ 遍历所有 agent session jsonl │ ├─ 跳过 trajectory 文件 │ ├─ 跳过 120 秒内未修改的文件(性能优化) │ ├─ 跳过 <100 字节的文件 │ └─ 统计 CHECK_WINDOW(120s) 内的 429 错误数 │ ├─ 判断 │ ├─ 有新 429 → consecutive++ │ └─ 无新 429 → consecutive=0(重置) │ └─ consecutive >= THRESHOLD(3) → 重启 Gateway + 重置计数 ``` ### 3.3 参数 | 参数 | 默认值 | 说明 | |------|--------|------| | CHECK_WINDOW | 120s | 检查最近多少秒的日志 | | THRESHOLD | 3 | 连续检测到多少次 429 才重启 | | 检测频率 | 60s | crontab 每分钟执行 | ### 3.4 状态文件 `/tmp/gateway-watchdog-429-count` — 记录连续 429 检测次数,重启后重置为 0。 ### 3.5 日志 `/tmp/gateway-watchdog.log` — 每次执行的检测结果。 ## 4. 文件位置 | 文件 | 路径 | |------|------| | 脚本 | `scripts/gateway-watchdog.sh` | | 本文档 | `docs/design/gateway-watchdog.md` | | 日志输出 | `/tmp/gateway-watchdog.log` | | 状态文件 | `/tmp/gateway-watchdog-429-count` | ## 5. 部署 ```bash # crontab 每分钟执行 (crontab -l 2>/dev/null | grep -v "gateway-watchdog"; \ echo "* * * * * /path/to/sanguo_moziplus_v2/scripts/gateway-watchdog.sh >> /tmp/gateway-watchdog.log 2>&1") \ | crontab - ``` ## 6. 运维 ```bash # 查看日志 tail -20 /tmp/gateway-watchdog.log # 查看当前 429 计数 cat /tmp/gateway-watchdog-429-count # 手动测试 bash scripts/gateway-watchdog.sh # 停用 crontab -l | grep -v "gateway-watchdog" | crontab - ``` ## 7. 已知局限 1. **事后检测** — 检测的是已发生的 429,不是预防 2. **重启治标** — 重启 Gateway 恢复 stalled session,但不解决 zhipu 限流根因 3. **无通知** — 重启后没有主动通知用户(可后续加飞书/邮件通知)