摘要:本文记录了一次完整的 OpenClaw(Copaw)进程崩溃排查过程。从系统重启前的大量日志入手,通过日志分析、内存监控、配置优化,最终定位根因并实施解决方案。生产环境内存占用降低 28%,单次压缩 Token 数降低 58%。适合遇到类似问题的开发者和运维人员参考。
关键词:OpenClaw、内存优化、进程崩溃、日志分析、生产环境
一、问题背景
1.1 系统环境
操作系统:Alibaba Cloud Linux 4 (Anolis OS)
内核版本:6.6.102-5.2.alnx4.x86_64
内存配置:约 2GB RAM
部署方式:单用户个人部署
进程名称:copaw (PID 2470)
1.2 故障现象
2026 年 3 月 2 日 19:41,系统发生非预期重启。重启前观察到以下异常:
- 系统无响应,SSH 连接断开
- 强制重启后,
journalctl --boot=-1显示重启前产生 11,456 条日志 copaw进程内存占用异常,接近系统承载上限
1.3 初步排查
# 查看重启前的系统日志
journalctl --boot=-1 --no-pager | grep -i "copaw\|memory\|oom" | tail -50
# 查看 copaw 进程日志
journalctl --boot=-1 -u copaw --no-pager | tail -100
关键日志片段:
Memory compaction triggered: estimated 237648 tokens
ping failed, err: no close frame received
WebSocket connection lost, reconnecting...
Context pruning: removed 18234 tokens from cache
二、根因分析
2.1 日志深度分析
通过统计日志类型分布,发现异常模式:
| 日志类型 | 数量 | 占比 |
|---|---|---|
| Memory Compaction | 3,241 | 28.3% |
| Context Pruning | 2,876 | 25.1% |
| WebSocket Ping/Pong | 4,102 | 35.8% |
| 其他 | 1,237 | 10.8% |
关键发现:
- 内存压缩(Memory Compaction)频繁触发
- 单次压缩 Token 数最高达 237,648
- WebSocket 连接因进程无响应而断开
2.2 内存压缩机制
OpenClaw 的内存压缩机制工作原理:
┌─────────────────────────────────────────────────────────┐
│ Context Cache │
│ (存储历史对话、工具调用结果、模型响应等) │
└─────────────────────────────────────────────────────────┘
↓
当 Token 数超过阈值时触发
↓
┌─────────────────────────────────────────────────────────┐
│ Memory Compaction │
│ (压缩历史上下文,保留关键信息,释放内存) │
└─────────────────────────────────────────────────────────┘
↓
压缩过程消耗大量 CPU 和内存
↓
┌─────────────────────────────────────────────────────────┐
│ 系统资源耗尽 → 进程无响应 │
└─────────────────────────────────────────────────────────┘
2.3 根因确认
根本原因:在 2GB 内存系统上,Copaw 进程的内存压缩操作处理了过多 Token(190k-237k),导致:
- 压缩过程本身消耗大量内存
- 系统可用内存不足,触发 OOM(Out of Memory)保护
- 进程无响应,WebSocket 连接断开
- 系统强制重启
三、解决方案
3.1 保护机制配置
3.1.1 Compaction Safeguard(压缩保护)
自适应 Token 预算,防止单次压缩处理过多数据:
{
"agents": {
"defaults": {
"compaction": {
"mode": "safeguard"
}
}
}
}
工作原理:
- 根据当前内存状态动态调整压缩预算
- 避免在内存紧张时触发大规模压缩
- 将压缩操作分散到多个时间段执行
3.1.2 Context Pruning(上下文修剪)
基于 TTL(Time To Live)的缓存清理策略:
{
"agents": {
"defaults": {
"contextPruning": {
"mode": "cache-ttl",
"ttl": "1h"
}
}
}
}
工作原理:
- 超过 1 小时未使用的上下文自动清理
- 优先保留最近活跃的会话
- 防止缓存无限增长
3.2 完整配置方案
针对 2GB 内存、20 用户以下的生产环境,推荐配置:
{
"session": {
"maxConcurrent": 5,
"dmScope": "per-channel-peer"
},
"agents": {
"defaults": {
"compaction": {
"mode": "safeguard"
},
"contextPruning": {
"mode": "cache-ttl",
"ttl": "1h"
},
"model": {
"contextTokens": 150000,
"maxConcurrent": 1
}
}
}
}
| 参数 | 值 | 说明 |
|---|---|---|
session.maxConcurrent |
5 | 全局最大并发会话数 |
session.dmScope |
per-channel-peer | 会话隔离级别(安全 DM 模式) |
compaction.mode |
safeguard | 启用压缩保护 |
contextPruning.ttl |
1h | 缓存存活时间 |
model.contextTokens |
150000 | 单会话最大 Token 数 |
model.maxConcurrent |
1 | 每用户最大并发模型调用 |
3.3 辅助优化措施
3.3.1 浏览器自动清理
OpenClaw 使用浏览器进行网页抓取,空闲页面会占用大量内存:
#!/bin/bash
# /root/.copaw/scripts/cleanup_browser.sh
# 查找空闲超过 10 分钟的浏览器进程
BROWSER_PIDS=$(pgrep -f "browser" | while read pid; do
IDLE_TIME=$(ps -o etime= -p $pid | awk -F: '{print $1 * 60 + $2}')
if [ "$IDLE_TIME" -gt 600 ]; then
echo $pid
fi
done)
# 关闭空闲浏览器
if [ -n "$BROWSER_PIDS" ]; then
echo "Closing idle browser processes: $BROWSER_PIDS"
kill $BROWSER_PIDS 2>/dev/null
fi
添加到定时任务(每 5 分钟执行):
*/5 * * * * /root/.copaw/scripts/cleanup_browser.sh
3.3.2 内存监控告警
#!/bin/bash
# /root/.copaw/scripts/monitor_memory.sh
COPAW_MEM=$(ps -o rss= -p $(pgrep -f "copaw") 2>/dev/null | awk '{print $1/1024}')
THRESHOLD=1500 # 1.5GB
if [ $(echo "$COPAW_MEM > $THRESHOLD" | bc) -eq 1 ]; then
echo "WARNING: Copaw memory usage: ${COPAW_MEM}MB (threshold: ${THRESHOLD}MB)"
# 可以添加邮件、钉钉、企业微信告警
fi
四、优化效果验证
4.1 实施前后对比
| 指标 | 实施前 | 实施后 | 改善 |
|---|---|---|---|
| 单次压缩 Token 数 | 237,648 | <100,000 | ↓58% |
| Copaw 内存占用 | 874MB | 630MB | ↓28% |
| 内存压缩频率 | 高频 | 自适应 | 显著降低 |
| 系统稳定性 | 崩溃重启 | 稳定运行 | ✅ |
| WebSocket 连接 | 频繁断开 | 稳定连接 | ✅ |
4.2 监控数据
# 查看当前内存使用
ps -o pid,rss,vsz,cmd -p $(pgrep -f "copaw")
# 输出示例:
# PID RSS VSZ CMD
# 2470 630MB 1.2GB copaw
4.3 日志验证
优化后日志片段:
Memory compaction triggered: estimated 87234 tokens
Compaction safeguard active: budget adjusted to 75000 tokens
Context pruning: removed 12456 tokens from cache (ttl: 1h)
关键变化:
- 单次压缩 Token 数从 237k 降至 87k
- Compaction Safeguard 生效,动态调整预算
- Context Pruning 定期清理过期缓存
五、最佳实践总结
5.1 配置原则
- 根据内存配置调整参数
- 2GB 内存:
contextTokens: 150000,maxConcurrent: 5 - 4GB 内存:
contextTokens: 300000,maxConcurrent: 10 - 8GB+ 内存:可适当放宽限制
- 2GB 内存:
- 启用所有保护机制
- Compaction Safeguard(必选)
- Context Pruning(必选)
- 会话隔离(多用户必选)
- 定期监控和清理
- 监控 Copaw 进程内存(告警线:75% 总内存)
- 清理空闲浏览器页面(每 5-10 分钟)
- 定期查看日志,发现异常模式
5.2 故障排查流程
1. 收集日志(journalctl、应用日志)
↓
2. 分析日志类型和频率(定位异常模式)
↓
3. 检查内存使用情况(ps、top、free)
↓
4. 查看配置参数(config.json)
↓
5. 实施保护措施(Compaction Safeguard、Context Pruning)
↓
6. 验证效果(监控数据、日志)
↓
7. 持续优化(根据实际使用情况调整)
5.3 常见误区
| 误区 | 正确做法 |
|---|---|
| 只关注应用日志,忽略系统日志 | 同时分析 journalctl 和应用日志 |
| 盲目增加内存,不优化配置 | 先优化配置,再考虑硬件升级 |
| 忽略浏览器内存占用 | 定期清理空闲浏览器页面 |
| 不设置告警,被动响应 | 配置内存监控告警,主动预防 |
六、企业部署建议
6.1 会话隔离
{
"session": {
"dmScope": "per-channel-peer"
}
}
说明:每个用户有独立的会话文件,防止用户间隐私泄露。
6.2 并发控制
{
"session": {
"maxConcurrent": 5
},
"agents": {
"defaults": {
"model": {
"maxConcurrent": 1
}
}
}
}
说明:
session.maxConcurrent:全局最大并发会话数model.maxConcurrent:每用户最大并发模型调用数
6.3 多 Gateway 架构(100+ 用户)
# 主 Gateway(端口 18789)
openclaw gateway run --profile main
# 救援 Gateway(端口 19001)
openclaw gateway run --profile rescue --port 19001
七、总结
本次故障排查的关键收获:
- 日志是第一位的:11,456 条日志看似杂乱,但统计分析后能清晰定位问题
- 保护机制必须启用:Compaction Safeguard 和 Context Pruning 是生产环境的必备配置
- 内存管理是系统工程:应用配置、浏览器清理、监控告警缺一不可
- 优化效果可量化:Token 数↓58%,内存↓28%,稳定性显著提升
对于使用 OpenClaw 的生产环境,建议:
- ✅ 立即启用 Compaction Safeguard
- ✅ 配置 Context Pruning(cache-ttl 模式)
- ✅ 设置内存监控告警(75% 总内存)
- ✅ 定期清理空闲浏览器页面
- ✅ 多用户部署必须启用会话隔离
附录:配置文件完整示例
{
"version": "1.0",
"session": {
"maxConcurrent": 5,
"dmScope": "per-channel-peer",
"timeout": "30m"
},
"agents": {
"defaults": {
"compaction": {
"mode": "safeguard",
"threshold": 0.75
},
"contextPruning": {
"mode": "cache-ttl",
"ttl": "1h",
"checkInterval": "5m"
},
"model": {
"contextTokens": 150000,
"maxConcurrent": 1,
"timeout": "60s"
}
}
},
"gateway": {
"port": 18789,
"auth": {
"token": "your-secret-token"
},
"allowFrom": ["127.0.0.1", "::1"]
},
"monitoring": {
"memoryThreshold": 1500,
"logLevel": "info",
"alertEnabled": true
}
}
参考资料
- OpenClaw 官方文档:https://docs.openclaw.ai
- OpenClaw 配置参考:https://docs.openclaw.ai/configuration-reference
- OpenClaw Gateway 运维手册:https://docs.openclaw.ai/gateway-runbook
🧙♂️ 关于作者
AI 炼金笔记(老赵),专注 AI 技术落地与价值转化。擅长将复杂的 AI 技术转化为可复用的"技术配方",帮助企业和个人提升效率、创造价值。
📱 公众号:AI 炼金笔记
🌐 博客:zhaojunwei.cn
🐱 GitHub:github.com/gavinz8
📧 合作:zhaojunweil@163.com