auto-sync: 2026-05-28 12:30:17
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# 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. **无通知** — 重启后没有主动通知用户(可后续加飞书/邮件通知)
|
||||
Reference in New Issue
Block a user