Files
sanguo_moziplus_v2/docs/design/gateway-watchdog.md
T
2026-05-28 12:30:17 +08:00

155 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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. **无通知** — 重启后没有主动通知用户(可后续加飞书/邮件通知)