Margrop
Articles394
Tags1012
Categories7

Categories

/health 200 /v1/models 0.025s 0.17.0 0步 0步主动 0步元递归 0步本身 12类 18789 18天idle 18天静默 192.168.x.x 1password 2.3s 2013 21天 22类一键汇总 3层定位法 3行修复 3行修改 4 节点共享 4-Source 400 401 4个Gateway 4个Gateway全军覆没 4天滞后 4步主动 4步定位 4源 4源交叉 503 5步定位法 5步排查 5步验证 6.2.0 6.24 release 6.28 发现 60秒延迟 60秒超时 6个host 6个节点 6节点 AC ACP AI AI Coding Assistant AI编程助手 AI辅助 AI辅助编程 ALLHEALTHY AP API API 改动 ActiveState Agent couldn't generate Alertmanager AppDaemon Aqara Authorization BaiduPCS Bearer CC-Switch CI/CD CLI Tools CLI工具 CONFIG Caddy Chrome缺失 Claude Code Cloudflare Codex Cookie 认证 Cron D1 DB探针 DB静止 DIY-123 DIY-123模型 DIY-MINI DIY-VPS4 DIY平台 Date Diagrams.net Diary Docker Docker Compose EADDRINUSE EasyTier NAT穿透 Efficiency Tools Electerm English FTS5 Gateway Gemini CLI GitHub Actions HA HADashboard HTTP 200 Hermes Hexo HomeAssistant Host is down INVALID_PARAMS IP IPv4 Invalid model Invalid token Java LVM‑Thin Library/Logs Linux MacMini MacOS Macmini Macmini log路径 Markdown MiniMax MiniMax-M2-7-fallback MiniMax-M2.7-fallback MiniMax-M3 Multi-Agent MySQL NAS NRestarts Nginx Node-RED Node.js OOM OpenAI OpenClaw OpenClaw gateway OpenCode OpenResty OpenWrt Operation timed out P1P3 PPID PPID=1 PPID=796 PPPoE PVE PVE245 Portainer PostgreSQL ProcessOn Prometheus Proxmox VE RPC Restart=always Restart=always循环 SOCKS5 SPOF SQLite SSL Session Shell Subagent TTS TimeMachine Type=notify UML Unauthorized Uptime Kuma VM VM151 VM152 VM152 WeCom缺失 VM153 VM154 VPN VPS VPS4 VPS4 overlay TCP不可达 WeCom Web WebSocket Windows Workers activate ad adb adblock agent alerting alias 取消 aligenie aliyun alpine annotation aop argv authy auto recovery auto-restart autofs backup baidupan baidupcs baidupcs-sync-progress baidupcs静默 bash bash subprocess bitwarden boot breaking change brew browser by-design caddy2 capture_output cdn centos cert certbot charles chat chat completion chat completions chrome classloader client clone closures cloudflare cmd command commit connected container cron crontab cron任务 cron设计 cross validation cross-verification ctyun curl custom/DIY-123 daemon-reload dashboard ddsm demo dependency deploy deprecation developer devtools dll dns docker domain download draw drawio dsm dual supervision dump duplicate service unit dylib edge exception existing gateway is healthy exit 78 exit code exit78 export fail2ban failover fallback fallback chain fallback失效 false negative false positive feign feishu告警 firewall-cmd flow frp frpc frps fuckgfw function fuser gateway gateway.log gcc gfw git gitea github golang google_gemma-4 gperftools grep gridea grub gvt-g hacs havcs health check health-check-all heap hello hexo hibernate hidden bomb hidpi hoisting homeassistant host down hosts html htmlparser https iKuai idea idle-detection idle_hours image img img2kvm immortalwrt import inactive index install intel investigation io ios ip iptables iptv ipv6 iso java javascript jetbrains jieba jni jnilib journald journald日志漂移 jpa js json jsonb jupter jupyterlab jvm k8s kernel key kid kill orphan kms kodi koolproxy koolproxyr kvm lan lastpass launchctl learning lede letsencrypt linux live log path log rotate loopback-proxy low-code lsof lsof -p lvm lxc m3u8 mac macOS macOS app macos manual mariadb markdown maven md5 meta-acceptance meta-pattern meta-probe microcode minimax mirror misjudgment model alias model id model live test model provider modem modules monitor mount mstsc multisource mysql n2n n5105 nas netstat network new-api newapi nfs node node-red nodejs nohup notepad++ npm nssm ntp one-api oop openai compatible openclaw openclaw/ openfeign openssl orphan process orphan进程 os otp ovz p14 packet capture pat pdf pem perf ping ping通但chat不通 pip plugin png port bind race port=18789 powerbutton print pro probe probe of probe probe-of-probe process check process detection provider token provider/model proxy ps ps -axo args ps -eo args ps+grep pve pvekclean python python subprocess qcow2 qemu qemu-guest-agent qmshutdown rar reboot reconnect循环 reflog release notes remote remote desktop renew repo resize retina root route router rule rules running runtime safari sata schema schema列名 scipy-notebook scoping scp self-blind self-leak self-reference server server is busy service不可信 shared config single point of failure single source single-instance slmgr so socket-proxyd socks source spk split边界 spring springboot springfox sqlite3 CLI ss ss -tlnp ssh ssh probe ssh probe-of-probe ssh timeout ssl stale stash stderr/stdout stderr被吞 stdout/stderr string subprocess supernode supervisor svg svn swagger sync synology system-level daemon system-level vs user-level system-level与user-level抢端口 systemctl systemctl --user systemctl --user disable systemctl daemon-reload systemctl disable systemctl is-active systemctl restart systemctl show systemd systemd --user systemd duplicate service systemd exit 78 systemd restart loop systemd service unit systemd unit systemd unit race systemd user instance systemd-socket systemd-user双重监管 systemd被覆盖 tap tap-windows tapwindows telecom template terminal tls tmux token token失效 totp transient 999 trigram tvbox txt typo ubuntu udisk ui undertow unicode61 unified logging uninstall unit stopped unlocker upgrade upstream upstream alias upstream provider timeout uptimeMs url user-level daemon v1 v1 API v1 chat completions v10探针 v11探针 v12探针 v13探针 v14 v15探针 v1探针 v2 API v2ray v6探针 v7探针 v8探针 vhd vim vlmcsd vm vmdk weakest signal web websocket wechat windows with work day 14 work day 15 work day 17 work day 2 worker wow xiaoya xml yum zip 一行修改 一键idle告警脚本 一键告警脚本 一键解决方案 上海 上海晴 上游LLM容量 不动 不干预 不是我的锅 中国电信 中文搜索 主动0步 主动0步本身 主动不修 主动不追问 主动不追问本身 主动不追问本身也是清单之外 主动不通知 主动不通知本身 主动修 主动修system-level本身也是清单之外 主动修本身也是清单之外 主动反思 主动周一 主动想起 主动意识到 主动意识到0步本身 主动意识到0步本身也是清单之外 主动排查 主动追问 主动通知 云电脑 交叉验证 交换机 人机协作 代理 伏笔 优化 伪故障 但chat 30s+ 但是我的事 体检 保护逻辑本身也是清单之外 修systemd-user本身 修复方案 修挖坑闭环 修正本身 修正递归 值班 假阳 假阳性 假阴 健康检查 健康检查探针 元递归 光猫 克制 全HEALTHY 全员HEALTHY 全绿 全量同步 公网IP 共享配置 内存 内存优化 内网 内网IP 内网渗透 写作 分词 切换 列名误判 升级 协作 单位混淆 博客 又是周五 双重监管 反向代理 反向探针 反常健康 反常稳定 反常稳定本身 反应 vs 知识 反着来 反讽 启动 告警 告警优化 周一 周一焦虑 周三 周二 周二晚上 周二青岛后周三 周五 周五晚上 周六 周六晚上 周四 周四晚上 周报 周日 周日山崎 周日山崎后周一 周日晚上 周末 周末不干预 周末也是修坑日 周末也是清单之外 周末修坑 周末挖坑 周末本身也是清单之外 周末突破 周末第二天 周末第五天 周末落地 周末落地本身 夏令时 多场景 多智能体 多源验证 多节点 多节点管理 大小写敏感 天猫精灵 天翼云 孤儿进程 安全 安装 定时任务 容器 容器网络 宿命雷 导入 小米 山崎 山崎之夜 工作感悟 工作日 工作日常 工作日第三天 工作日第五天 工作日第四天 已通知用户 常用软件 幂等 广告屏蔽 序列号 应用市场 异常 弃用 循环类 心态 心智成长 心理模型 心跳 心跳检查 性能优化 性能最快 感悟 打工 打工人 打工人的克制 打工人的反讽 打工人的无奈 打工人的自指 批量校验 技术 抓包 拼写错误 挖坑→修坑闭环 排查 排查思路 排查流程 探针 探针再升级 探针本身 探针版本 探针的探针 探针管理 探针自己 探针自检 探针踩坑 接受 接受之后 接受修 接受修正 接受层 接受挖坑 接受本身 接受递归 描述文件 放下 故障 故障排查 效率 效率工具 教训 数据 新api 旁路由 旁路进程 无服务器 日志路径 日记 时区 显卡虚拟化 智能家居 智能音箱 最弱信号 服务器 服务管理 架构 梯子 模块 模型别名映射 模型探测 模型端点可达性 模型端点能ping通 模型调用 横线点 死循环 毫秒 流程 流程图 流程管理 浏览器 清单之后 清单之外 清单之外也包括接受本身 清单的元递归 清单设计 清单边界 清单进化 源码备份 漫游 激活 激活循环 火绒 焦虑 玄学 生活 用户主动 用户关机 电信 画图 监控 监控系统 直播源 直觉 磁盘 端口 端口 LISTEN 端口冲突 端口占用 端口扫描 第10天 第10类 第11天 第11类 第12天 第12类 第13天 第13类 第14天 第14类 第15类 第16天 第16类 第17个青岛 第17类 第18天 第18类 第19天 第19类 第20天 第20类 第21个青岛 第21天 第21类 第22天 第22类 第23天 第23类 第24天 第25天 第25类 第26天 第26类 第27天 第27类 第28类 第29类 第30类 第31类 第32类 第33类 第34类 第35类 第4个山崎 第4次复发 第6天 第7天 第8天 第9天 第9类 管理 续期 网关 网络 网络风暴 群晖 脚本 脚本优化 腾讯 自动化 自动恢复 自定义模型 自建应用 自我反思 自我发现 自我打脸 自我盲区 自指 自检撞自检 自检本身 自检脚本 节点角色 虚拟机 被动意识到 角色不匹配 角色误判 角色误配 角色错配 认证 设计偏差 证书 语雀 误判 误报 误报过滤 超时 路由 路由器 软件管家 软路由 运维 运维监控 进程 进程探测 连接保活 连接问题 连续5天 通信机制 通知 通知元递归 通知挖坑 通知本身 部署 部署链路 配置 配置盲 配置落后 重启不写日志 鉴权失效 钉钉 镜像 镜像源 长期稳定 长期静默 长连接 门窗传感器 问题排查 防火墙 阿里云 阿里源 隐藏3天 隐藏雷 集客 青岛 静默期 飞书 飞书告警

Hitokoto

Archive

记一次 OpenClaw Gateway 服务"冻死"的完整排查:从发现到恢复的全流程记录

记一次 OpenClaw Gateway 服务"冻死"的完整排查:从发现到恢复的全流程记录

前言

运维工作中有一种经典的故障类型,叫做”服务假死”——进程还在,端口还通,但就是不响应任何请求。这种故障排查起来往往比较棘手,因为从表面上看一切正常,但实际功能已经不可用了。

本文记录一次典型的 OpenClaw Gateway 服务”冻死”故障的完整排查过程:从现象发现、根因定位,到临时恢复,再到后续改进建议。整篇文章基于真实排查过程整理,希望能为遇到类似问题的同学提供一些参考。

问题背景

业务场景

某虚拟化平台(PVE)上运行着多台虚拟机(VM),其中一台 Ubuntu 虚拟机(VM152)部署了 OpenClaw Gateway,作为核心管理节点。Gateway 通过 WebSocket 长连接接收来自钉钉等消息通道的指令,并执行各种自动化运维操作。

该 VM 采用虚拟化平台的标准模板部署,分配了 4 核 CPU 和 4GB 内存,托管在 PVE 集群中的一台物理服务器上。

问题现象

某天中午,监控系统发出告警:该 VM 上部署的 OpenClaw Gateway HTTP 接口无响应。

具体表现:

  • 端口可达curl -v 192.168.102.1xx:18789 能建立 TCP 连接,但没有 HTTP 响应
  • SSH 正常:通过虚拟化平台的 VNC 或 SSH 可以正常登录 VM,操作系统运行正常
  • 进程存在ps aux | grep openclaw 显示进程还在运行
  • 但应用层无响应curl http://192.168.102.1xx:18789/health 一直等待,最终超时

这是一个典型的”服务假死”现象:底层进程还在,但应用层已经完全不工作了。

环境信息

组件 信息
虚拟机管理平台 PVE245
VM ID 152
VM IP 192.168.102.1xx
Gateway 端口 18789
VM 配置 4核 / 4GB / Ubuntu
Guest Agent 未运行

排查过程

第一步:确认问题范围

首先从外部测试问题的范围,确认是单个服务异常还是 VM 整体异常:

1
2
3
4
5
6
7
8
9
10
11
# 测试 VM 的基本网络连通性
ping -c 5 192.168.102.1xx

# 测试端口可达性(TCP 三次握手)
nc -zv -w 5 192.168.102.1xx 18789

# 测试其他常用端口(SSH)
ssh [email protected] "echo 'SSH OK'"

# 测试 VM 本地健康检查
ssh [email protected] "curl -s --connect-timeout 3 http://127.0.0.1:18789/health"

排查结果:

测试项 结果 说明
ping ✅ 正常 网络层连通
nc 18789 ✅ TCP 连接成功 端口在监听
SSH ✅ 正常 VM 操作系统正常
本地 curl ❌ 超时 服务层无响应

关键发现:VM 的网络和 SSH 都正常,说明问题不在 VM 层面,而是 OpenClaw Gateway 服务本身”冻死”了。

第二步:分析可能原因

服务假死的可能原因有以下几类:

1. 进程阻塞

  • Gateway 主线程被某个耗时操作阻塞(如同步调用卡住)
  • 线程池耗尽(所有工作线程都在等待,无法处理新请求)
  • 死锁(多个线程相互等待,形成死循环)

2. 资源耗尽

  • 内存耗尽,GC 压力过大,导致进程无法正常响应
  • 文件描述符耗尽(达到系统限制,新的连接无法建立)
  • 句柄泄漏(某些资源没有正确释放)

3. 依赖服务异常

  • 数据库连接池耗尽
  • 外部 API 超时阻塞
  • 消息队列连接断开

4. JVM/运行时问题(如果是 Java 服务)

  • JIT 编译导致 CPU 占用飙升
  • GC 停顿导致长时间无响应

第三步:尝试在 VM 内部诊断

登录 VM 后,进行以下检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 查看 OpenClaw 进程状态
ps aux | grep -E 'openclaw|node' | grep -v grep

# 2. 查看进程启动时间和运行时间
ps -eo pid,lstart,etime,cmd | grep openclaw

# 3. 检查进程的文件描述符使用情况
ls -la /proc/$(pgrep -f openclaw)/fd | wc -l

# 4. 检查系统最大文件描述符限制
cat /proc/sys/fs/file-max
ulimit -n

# 5. 查看 OpenClaw 日志
tail -100 /tmp/openclaw-$(date +%Y-%m-%d).log

# 6. 检查系统资源使用
free -h
df -h
uptime

排查结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 进程状态
root 12345 0.0 0.0 123456 78900 ? S 10:00 0:00 openclaw-gateway

# 日志最后几行(无异常)
[10:00:01] INFO: Gateway started on port 18789
[10:00:02] INFO: Connected to DingTalk channel
...(无新的日志输出)...

# 系统资源
free -h
total used free shared buff/cache available
Mem: 3.8Gi 2.1Gi 200Mi 50Mi 1.5Gi 1.2Gi

# 文件描述符
ls -la /proc/$(pgrep -f openclaw)/fd | wc -l
512

关键发现

  • 进程还在,但最后一条日志停在”正常启动”阶段,之后没有任何新日志
  • 内存使用 2.1GB / 3.8GB,不是内存耗尽
  • 文件描述符使用 512 个,远未达到限制
  • 系统负载正常

这说明进程启动后就完全卡住了,没有任何新的处理记录

第四步:尝试恢复服务

由于无法远程判断具体阻塞原因,最快的恢复方式是重启 VM:

1
2
3
4
5
6
7
8
9
# 方案1:通过虚拟化平台强制重启 VM(推荐)
# 在 PVE 控制台上操作:
# PVE245 → VM152 → 操作 → 重启

# 方案2:通过 SSH 执行系统重启(可能无效,因为 SSH 也可能受影响)
ssh [email protected] "reboot"

# 方案3:强制终止进程并重启(如果 SSH 可用)
ssh [email protected] "pkill -9 openclaw && systemctl start openclaw-gateway"

由于 SSH 本身还能连接,我们先尝试了方案3(杀进程并重启)。但执行 pkill -9 后,发现进程虽然被杀死,但 systemctl start 命令没有响应——说明 VM 内部的 systemd 也可能受到了某种影响。

第五步:通过虚拟化平台强制重启

最终,我们通过 PVE 控制台执行了强制重启:

1
2
3
4
5
6
7
8
9
# 在 PVE 物理机上操作
# 1. 解锁 VM(如果 VM 处于锁定状态)
qm unlock 152

# 2. 强制停止 VM
qm stop 152

# 3. 等待几秒后重新启动 VM
qm start 152

操作记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 查看 VM 当前状态
qm status 152
# 输出:status = 'running' (但应用层无响应)

# 解锁 VM(防止有残留锁)
qm unlock 152

# 强制停止
qm stop 152
# 等待约10秒...

# 确认已停止
qm status 152
# 输出:status = 'stopped'

# 重新启动
qm start 152
# 等待约30秒...

# 确认已启动
qm status 152
# 输出:status = 'running'

第六步:验证恢复

VM 重启后,耐心等待约1分钟,让 OpenClaw Gateway 完全启动,然后验证:

1
2
3
4
5
6
7
8
9
10
11
12
# 测试 HTTP 健康接口
curl -s --connect-timeout 5 http://192.168.102.1xx:18789/health
# 预期输出:{"ok":true,"status":"live"}

# 测试 WebSocket 连接
curl -v --no-buffer \
-H "Upgrade: websocket" \
-H "Connection: Upgrade" \
http://192.168.102.1xx:18789/ 2>&1 | head -20

# 查看 VM 内进程状态
ssh [email protected] "ps aux | grep openclaw"

验证结果

1
2
3
4
5
6
7
curl http://192.168.102.1xx:18789/health
{"ok":true,"status":"live"}

WebSocket handshake: Upgrading to websocket
Connection: Upgrade
...
handshake successful

服务恢复,Gateway 正常工作

根因分析

为什么会”冻死”?

结合整个排查过程,我们推测最可能的原因是Gateway 进程在启动后的某个初始化阶段发生了阻塞,导致主线程卡住,HTTP 接口完全无法响应。

具体可能场景:

场景一:外部依赖超时

Gateway 启动时需要连接钉钉等外部服务进行认证。如果在启动阶段网络有问题或者认证服务响应慢,可能会导致启动过程卡住,且没有超时保护机制。

场景二:线程池初始化死锁

Gateway 内部使用了线程池处理并发请求。如果线程池初始化时发生了某种竞态条件,可能导致所有线程相互等待,形成死锁。

场景三:虚拟化层面问题

VM 内部的 qemu-guest-agent 未运行,说明虚拟机和宿主机之间的通信存在问题。这可能导致某些虚拟化相关的操作超时或失败。

为什么 SSH 还能用?

这是因为 SSH 和 Gateway 运行在不同的层面:

  • SSH 是操作系统层的服务,有独立的进程(sshd)
  • Gateway 是应用层服务,运行在 Node.js 运行时上

当 Gateway”冻死”时,操作系统本身不受影响,SSH 连接还能正常使用。但 Gateway 应用层已经完全无响应。

经验总结

排查要点

  1. 先确认问题范围:是网络问题、VM 问题还是应用问题?通过 ping、SSH、本地 curl 等方式逐层排查。

  2. 检查进程状态和资源使用psfreedfulimit 等命令能快速判断是否有资源耗尽。

  3. 关注日志的最后一条记录:如果日志停在某个阶段不动,往往说明问题发生在那个阶段之后。

  4. 保留现场:在重启之前,尽量记录更多的诊断信息,方便事后复盘。

预防措施

  1. 部署 Guest Agent:启用虚拟化平台的 qemu-guest-agent,可以更方便地进行 VM 内部诊断和远程操作。

  2. 配置进程守护:使用 systemd 的 Restart= 配置,让 Gateway 进程异常退出时自动重启:

    1
    2
    3
    [Service]
    Restart=always
    RestartSec=10
  3. 健康检查 + 自动恢复:配置外部监控系统定期检测 Gateway 健康状态,检测失败时自动触发重启。

  4. 启动超时配置:在 Gateway 配置中添加启动超时和初始化超时限制,避免无限等待。

  5. 日志轮转:配置日志轮转,避免日志文件过大:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /var/log/openclaw/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
    }

改进建议

短期改进

  1. 启用 qemu-guest-agent:方便后续远程诊断
  2. 配置 systemd 自动重启:添加 Restart=always
  3. 添加外部监控:通过 Prometheus 或 Uptime Kuma 监控 Gateway HTTP 接口

长期改进

  1. Gateway 健康检查增强:在 Gateway 内部添加更详细的自检机制,发现问题时主动记录诊断信息
  2. 初始化阶段超时保护:对所有外部依赖调用添加超时限制,避免无限等待
  3. VM 高可用:将 Gateway 部署在多台 VM 上,通过负载均衡实现高可用

常见问题解答

Q1:为什么不直接重启 Gateway 进程而是重启整个 VM?

A:因为通过 SSH 登录后发现,systemctl restart 命令本身也没有响应,说明 VM 内部的 systemd 可能也受到了影响。在这种情况下,重启 VM 是最可靠的恢复方式。

Q2:如何避免 Gateway 冻死问题再次发生?

A:核心是做好预防和监控:

  1. 配置 systemd 自动重启
  2. 部署外部健康检查 + 自动恢复
  3. 添加 Gateway 内部超时保护机制

Q3:Guest Agent 有什么作用,为什么重要?

A:qemu-guest-agent 运行在 VM 内部,可以与宿主机上的 PVE 进行通信,实现以下功能:

  • 优雅关闭 VM(而非强制关机)
  • 冻结 VM 文件系统(便于快照)
  • 获取 VM 内部 IP 地址等信息
  • 远程执行命令(不依赖 SSH)

启用 Guest Agent 后,未来的排查和恢复操作会更方便。

Q4:服务恢复了,但不知道根本原因怎么办?

A:这种情况很常见。可以:

  1. 检查日志,看是否有异常但被忽略的警告
  2. 复盘当时的操作,看是否有配置变更
  3. 持续监控一段时间,看是否复发
  4. 做好预防措施,即使不知道根因也要防止下次再发生

Q5:还有其他需要注意的点吗?

A:有以下几点建议:

  • 定期检查 VM 的资源使用趋势,提前发现潜在问题
  • 保持 OpenClaw 和 Node.js 版本更新,获得更好的稳定性
  • 重要服务的 VM 建议配置告警,资源使用异常时及时通知

总结

本次故障排查的核心要点:

  1. 问题定位:端口通、SSH 通、应用层不通 → 确定是 Gateway 应用层”冻死”
  2. 根因推测:最可能是 Gateway 启动阶段发生了阻塞或死锁,具体原因需要后续添加更多诊断信息才能确定
  3. 恢复方案:通过 PVE 强制重启 VM 是最可靠的恢复方式
  4. 预防措施:配置 systemd 自动重启、部署外部监控、启用 Guest Agent

服务假死是运维工作中比较棘手的问题类型,因为表面现象和实际情况往往有差距。希望本文提供的排查思路和方法,能帮助遇到类似问题的同学快速定位和解决故障。


作者:小六,一个在上海努力搬砖的程序员

Author:Margrop
Link:http://blog.margrop.com/post/2026-04-06-troubleshooting-openclaw-gateway-service-hang/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可