ClawdBot日志分析:定位Gateway not reachable异常的5个关键点

ClawdBot日志分析:定位Gateway not reachable异常的5个关键点

ClawdBot 是一个面向个人用户的本地化 AI 助手,设计目标是“开箱即用、隐私可控、模型可换”。它不依赖云端 API,所有推理任务默认在本地设备完成,后端由 vLLM 提供高性能大模型服务,前端提供 Web 控制台与 CLI 工具,支持多智能体协作、工作区管理、上下文压缩等实用功能。其核心通信架构采用 WebSocket 网关(Gateway)模式,所有通道(如 Telegram、Web UI、CLI)均通过统一网关与后端模型服务对接——这也意味着,一旦网关失联,整个系统将表现为“有界面、无响应、发不出消息、查不到状态”。

Gateway not reachable 这一错误提示,正是 ClawdBot 日志中最常出现、却最容易被误判为“网络问题”或“模型没起来”的典型故障信号。它看似简单,实则横跨配置、网络、权限、生命周期、协议兼容五大层面。本文不讲原理堆砌,不列长篇配置模板,而是基于真实部署场景(含树莓派、Docker 容器、WSL、物理服务器),从日志线索出发,梳理出定位该异常的 5 个不可跳过的检查关键点——每一点都对应一类高频误操作,每一个都能在 2 分钟内验证并闭环。

1. 网关进程是否真正运行:别被“ps aux | grep clawd”骗了

很多人看到终端里有 clawdbot gateway 进程就以为网关已就绪,但实际中,ClawdBot 的 Gateway 是一个按需启动、带健康检查的守护式子进程。它不会随主程序永久驻留,而是在首次收到通道请求(如打开 Web UI、执行 clawdbot channels status)时才拉起,并持续监听 ws://127.0.0.1:18780。若进程因初始化失败退出,CLI 可能仍显示“running”,但 WebSocket 服务早已静默终止。

1.1 快速验证方法

直接用 curl 检查 WebSocket 握手能力(无需客户端):

# 尝试发起 WebSocket 升级请求(返回 101 表示成功) curl -i -N -H "Connection: Upgrade" \ -H "Upgrade: websocket" \ -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \ -H "Sec-WebSocket-Version: 13" \ http://127.0.0.1:18780 
  • 若返回 HTTP/1.1 101 Switching Protocols → 网关进程存活且监听正常
  • ❌ 若返回 Connection refused 或超时 → 网关未启动或端口被占用
  • 若返回 HTTP/1.1 400 Bad Request → 网关在运行,但拒绝非法握手(属正常)

1.2 常见陷阱与修复

  • 陷阱1:Docker 容器未暴露 18780 端口
    docker run 启动时遗漏 -p 18780:18780,导致宿主机无法访问容器内网关。
    修复:补加端口映射,或改用 host 网络模式(--network host
  • 陷阱2:systemd 服务未启用网关子模块
    自定义 systemd unit 文件中只写了 ExecStart=/usr/bin/clawdbot start,未指定 --gateway 标志。
    修复:改为 ExecStart=/usr/bin/clawdbot start --gateway
  • 陷阱3:vLLM 服务未就绪,网关主动退避
    网关启动时会探测 http://localhost:8000/v1/models,若超时(默认 5s),将放弃启动并静默退出。
    验证:curl -s http://localhost:8000/v1/models | jq .;若失败,先确保 vLLM 已 --host 0.0.0.0 启动且可访问。
关键结论ps 看进程只是第一层表象;curl 测试 WebSocket 握手才是判断网关“活没活”的黄金标准。不要跳过这一步。

2. 网关绑定地址与通道请求源是否匹配:loopback 不等于 localhost

日志中明确提示:
Gateway target: ws://127.0.0.1:18780
Source: local loopback
Bind: loopback

这三行信息共同指向一个常被忽视的细节:ClawdBot 默认将网关绑定到 127.0.0.1(IPv4 loopback),而非 localhost0.0.0.0。而 localhost 在部分系统(尤其启用了 IPv6 的 Linux)中可能解析为 ::1(IPv6 loopback),导致 DNS 解析后的连接目标与网关监听地址不一致。

2.1 验证 DNS 解析行为

# 查看 localhost 解析结果 getent hosts localhost # 输出示例(问题场景): # ::1 localhost ip6-localhost ip6-loopback # 此时,CLI 或 Web UI 若用 'localhost' 构造 ws URL,将尝试连 ::1:18780 → 失败 

2.2 两种可靠修复路径

路径B:统一禁用 IPv6 解析(系统级)
编辑 /etc/gai.conf,取消注释并修改:

precedence ::ffff:0:0/96 100 

使 localhost 优先解析为 IPv4。

路径A:强制使用 IPv4 地址(推荐)
修改 clawdbot.json 中所有涉及网关地址的配置项,显式写死 127.0.0.1

{ "gateway": { "bind": "127.0.0.1:18780", "publicUrl": "ws://127.0.0.1:18780" } } 

并重启服务。

2.3 Docker 场景特别注意

在容器内,127.0.0.1 指向容器自身,而宿主机 CLI 执行 clawdbot channels status 时,请求发向的是宿主机的 127.0.0.1(即宿主机 loopback),而非容器内网关。此时必须:

  • 容器启动时使用 --network host,或
  • 将网关 bind 改为 0.0.0.0:18780publicUrl 设为宿主机 IP(如 ws://192.168.1.100:18780),并确保防火墙放行。
关键结论127.0.0.1localhost0.0.0.0。网关的 bind 地址、CLI/Web 的请求地址、Docker 的网络模式,三者必须逻辑自洽。拿不准时,统一用 127.0.0.1 最安全。

3. 配置文件中的 gateway 字段是否被意外覆盖或缺失

ClawdBot 的配置加载遵循“多源合并”策略:环境变量 > CLI 参数 > clawdbot.json > 默认值。而 gateway 配置块恰恰是极易被上层覆盖的敏感区域。常见情况是:用户修改了 models.providers.vllm.baseUrl,却忽略了同步更新 gateway.publicUrl,导致通道尝试连接旧地址。

3.1 快速定位配置冲突

执行以下命令,输出最终生效的完整配置快照(含所有合并结果):

clawdbot config dump --resolved 

在输出中搜索 gateway,重点关注:

"gateway": { "bind": "127.0.0.1:18780", "publicUrl": "ws://127.0.0.1:18780", // ← 此处必须与实际监听地址一致 "healthCheckInterval": 5000 } 

3.2 高危配置模式(务必检查)

配置位置危险示例后果
.env 文件CLAWDBOT_GATEWAY_PUBLIC_URL=ws://localhost:18780覆盖 JSON 中的 127.0.0.1,触发 IPv6 解析失败
CLI 启动参数clawdbot start --gateway-public-url ws://10.0.0.5:18780若该 IP 宿主机不可达,则所有通道失联
clawdbot.json"publicUrl": "wss://mydomain.com" 但未配 TLS 证书WebSocket 升级失败,报错 Error: unexpected server response (400)

3.3 安全配置实践

  • 开发/单机环境:publicUrlbind 保持一致,均用 ws://127.0.0.1:18780
  • 生产/反代环境:bind 仍为 127.0.0.1:18780publicUrl 设为反代后地址(如 wss://ai.yourdomain.com),并在 Nginx 中配置 WebSocket 透传:
location / { proxy_pass http://127.0.0.1:18780; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } 
关键结论clawdbot config dump --resolved 是排查配置类问题的终极命令。不要凭记忆修改,一定要看最终合并结果。

4. 网关健康检查失败:1006 错误背后的 3 种真实原因

日志中 Error: gateway closed (1006 abnormal closure (no close frame)) 是 WebSocket 协议级错误码,表示连接被非正常关闭,且对方未发送标准关闭帧。这通常不是网络中断,而是网关进程在握手后、业务通信前就崩溃了。根本原因集中在以下三类:

4.1 内存不足(OOM Killer 杀死网关)

ClawdBot 网关虽轻量,但需维持 WebSocket 连接池、消息队列、心跳管理。在低内存设备(如 2GB RAM 树莓派)上,若同时运行 vLLM(Qwen3-4B 占约 3.2GB VRAM + 1.5GB RAM),网关可能因 OOM 被系统杀死。

验证:dmesg -T | grep -i "killed process" | grep clawd
修复:限制 vLLM 内存使用(--max-model-len 2048 --gpu-memory-utilization 0.8),或为网关单独分配 swap(sudo fallocate -l 2G /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile

4.2 模型服务响应超时,网关主动断连

网关在转发用户请求前,会先向 vLLM 发起 POST /v1/chat/completions 健康探测。若 vLLM 因加载模型慢、GPU 显存不足、CUDA 初始化失败等原因,超过 gateway.healthCheckTimeout(默认 8s)未响应,网关将关闭连接并报 1006。

验证:手动调用探测接口

curl -X POST http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"Qwen3-4B-Instruct-2507","messages":[{"role":"user","content":"ping"}]}' 

若超时或返回 500,问题在 vLLM 层。

4.3 TLS/SSL 配置冲突(仅当启用 wss)

publicUrlwss:// 开头,但网关未配置有效证书,或客户端(如浏览器)证书校验失败,也会触发 1006。

验证:用 wscat 绕过浏览器校验

npx wscat -c wss://yourdomain.com --no-check 

若成功连接,则问题在客户端证书信任链;若失败,则网关 TLS 配置有误。

关键结论:1006 不是“连不上”,而是“连上后立刻崩”。重点查系统日志(OOM)、vLLM 健康度、TLS 配置三者,而非抓包看网络层。

5. 通道代理设置与网关通信的隐式冲突

这是最隐蔽也最易复现的坑:当用户为 Telegram 通道配置了 proxy(如 "proxy": "http://127.0.0.1:7890"),ClawdBot 会全局复用该代理设置,导致网关自身的健康检查请求也被送往代理,而代理显然无法处理 ws://127.0.0.1:18780 这类本地回环地址。

日志中 Source: local loopback 的提示,正是 ClawdBot 在告诉你:“我本想直连,但代理规则把它劫走了”。

5.1 立即验证方法

查看网关启动时的日志(非 channels status 日志):

# 查找网关初始化日志 journalctl -u clawdbot -n 100 | grep -A5 "Starting gateway" # 关键线索:若出现 "Using proxy http://127.0.0.1:7890 for gateway health check" → 确认冲突 

5.2 彻底解决方案

  • 方案1(推荐):为网关禁用代理
    clawdbot.json 中显式关闭网关代理:
"gateway": { "disableProxy": true, "bind": "127.0.0.1:18780" } 
  • 方案2:代理规则排除本地地址
    若使用 Clash/Quantumult,添加规则:
RULE-SET,LOCAL,PROXY,no-resolve RULE,127.0.0.1,PROXY,force RULE,localhost,PROXY,force 

并确保 clawdbot.jsonproxy 字段设为 null 或删除。

  • 绝对避免:在 channels.telegram.proxy 中配置代理的同时,又让网关走同一代理——这是设计上的逻辑矛盾。
关键结论:Telegram 通道的 proxy 是给 Telegram API 用的,不是给本地网关用的。二者网络路径完全独立,强行复用必出问题。

总结:5 个关键点的检查顺序与决策树

面对 Gateway not reachable,请严格按此顺序排查,90% 的问题可在 5 分钟内定位:

  1. 先跑 curl 握手测试 → 不通?跳到第 2 步;通?跳到第 4 步
  2. clawdbot config dump --resolvedgateway.publicUrl → 是否为 127.0.0.1?否?修正并重启
  3. 确认网关进程真实存活ps + curl 双验证;若挂了,查 journalctl -u clawdbot 看启动报错
  4. 验证 vLLM 健康度curl 测试 /v1/models/v1/chat/completions;失败则修 vLLM
  5. 检查代理配置污染 → 搜索日志中 proxy 相关关键词;存在则按方案1禁用网关代理

记住:ClawdBot 的设计哲学是“每个组件职责单一”。网关只管 WebSocket 连接,vLLM 只管模型推理,Telegram 通道只管消息收发。把它们当成三个独立服务去诊断,远比当成一个黑盒去猜更高效。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 ZEEKLOG星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Read more

鸿蒙 App 如何设计 AI 原生的信息架构

鸿蒙 App 如何设计 AI 原生的信息架构

子玥酱(掘金 / 知乎 / ZEEKLOG / 简书 同名) 大家好,我是子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。 我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括前端工程化、小程序、React / RN、Flutter、跨端方案, 在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。 技术方向:前端 / 跨端 / 小程序 / 移动端工程化 内容平台:掘金、知乎、ZEEKLOG、简书 创作特点:实战导向、源码拆解、少空谈多落地 文章状态:长期稳定更新,大量原创输出 我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、

By Ne0inhk

Node.js 安装指南(Mac 版本)

第一章:准备工作与环境检查 1.1 确认系统要求 在开始安装 Node.js 之前,首先需要确认您的 Mac 系统是否符合要求: 系统版本要求: * macOS 10.10 (Yosemite) 或更高版本 * 推荐使用 macOS 10.15 (Catalina) 或更新版本 * 同时支持 Intel 和 Apple Silicon (M1/M2) 芯片 检查您的 macOS 版本: 1. 点击屏幕左上角的 Apple 菜单 2. 选择"关于本机" 3. 查看显示的版本信息 通过终端检查: bash sw_vers

By Ne0inhk
Flutter for OpenHarmony:phone_numbers_parser 国际电话号码的解析、验证与格式化(全球化号码处理) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:phone_numbers_parser 国际电话号码的解析、验证与格式化(全球化号码处理) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 随着应用出海,处理全球各地的手机号码成为刚需。不同国家的号码格式千奇百怪:有的带国家码(+86),有的带括号,有的带空格。如何验证用户输入的号码是否合法?如何将其格式化为标准的 E.164 用于后端存储? phone_numbers_parser 是 Dart 生态中优秀的电话号码处理库,它是 Google libphonenumber 的轻量级 Dart 移植版,不依赖任何原生代码,因此在 OpenHarmony 上运行时无需任何额外配置,且包体积极小。 一、概念介绍/原理解析 1.1 基础概念 * E.164: 国际电信联盟定义的标准号码格式(如 +8613800138000),后端存储通常使用此格式。 * National: 本地显示格式(如

By Ne0inhk

Flutter for OpenHarmony: Flutter 三方库 plugin_platform_interface 规范鸿蒙插件跨端接口契约(插件开发标准指南)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在进行 OpenHarmony 插件开发时,一个核心挑战是如何确保你的插件在 Android、iOS 和鸿蒙等多端表现一致。为了保证扩展的可测试性和规范性,Flutter 团队提出了一套“基于接口”的插件架构规范。 plugin_platform_interface 正是实现这一架构的官方基石。它通过强行校验开发者是否继承了特定的基类,确保任何三方开发者(或你自己在进行鸿蒙适配时)在模拟或重写平台库时,都能遵循严格的协议契约,防止因漏写方法而导致的运行时崩溃。 一、标准分层插件架构 该库致力于定义中间的“平台接口层(Platform Interface)”。 注册实现 注册实现 通过校验器 Flutter App 插件 API (面向用户) Platform Interface (定义契约) 鸿蒙特定实现 (ArkTS 交互) Android 特定实现

By Ne0inhk