跳转至

Gateway 服务和进程

网关服务未运行

当服务已安装但进程无法保持运行时使用。

openclaw gateway status
openclaw status
openclaw logs --follow
openclaw doctor
openclaw gateway status --deep   # also scan system-level services

查找以下情况:

  • Runtime: stopped 及退出提示。
  • 服务配置不匹配(Config (cli) 与 Config (service))。
  • 端口/监听器冲突。
  • 使用 --deep 时,额外的 launchd/systemd/schtasks 安装。
  • Other gateway-like services detected (best effort) 清理提示。
常见特征
  • Gateway start blocked: set gateway.mode=local 或 existing config is missing gateway.mode → 未启用本地网关模式,或配置文件被覆盖并丢失了 gateway.mode。修复:在配置中设置 gateway.mode="local",或重新运行 openclaw onboard --mode local / openclaw setup 以重新写入预期的本地模式配置。如果你通过 Podman 运行 OpenClaw,默认配置路径为 ~/.openclaw/openclaw.json。
  • refusing to bind gateway ... without auth → 非回环绑定但没有有效的网关认证路径(token/password,或已配置的 trusted-proxy)。
  • another gateway instance is already listening / EADDRINUSE → 端口冲突。
  • Other gateway-like services detected (best effort) → 存在过期或并行的 launchd/systemd/schtasks 单元。大多数部署应每台机器保留一个网关;如果确实需要多个,请隔离端口 + 配置/状态/工作区。参见 /gateway#multiple-gateways-same-host。
  • doctor 中的 System-level OpenClaw gateway service detected → 存在 systemd 系统单元,而用户级服务缺失。在允许 doctor 安装用户服务之前,删除或禁用重复项;如果系统单元是预期的服务管理器,请设置 OPENCLAW_SERVICE_REPAIR_POLICY=external。
  • Gateway service port does not match current gateway config → 已安装的服务管理器仍固定使用旧的 --port。运行 openclaw doctor --fix 或 openclaw gateway install --force,然后重启网关服务。

相关:

macOS 网关静默停止响应,触碰仪表盘后恢复

当 macOS 主机上的渠道(Telegram、WhatsApp 等)间歇性静默数分钟到数小时,并且网关似乎在你打开 Control UI、SSH 登录或以其他方式与主机交互的瞬间恢复时使用。通常 openclaw status 中没有明显症状,因为等你查看时网关已经再次存活。

ls ~/.openclaw/logs/stability/ | tail -5
openclaw gateway stability --bundle latest
pmset -g log | grep -iE "sleep|wake|maintenance" | tail -50
launchctl print gui/$UID/ai.openclaw.gateway | grep -E "state|last exit|runs"

查找以下情况:

  • ~/.openclaw/logs/stability/ 中有一个或多个 *-uncaught_exception.json 稳定性捆绑包,其 error.code 设置为临时网络代码,例如 ENETDOWN、ENETUNREACH、EHOSTUNREACH 或 ECONNREFUSED。
  • 与崩溃时间戳对齐的 pmset -g log 行,例如 Entering Sleep state due to 'Maintenance Sleep' 或 en0 driver is slow (msg: WillChangeState to 0)。Power Nap / Maintenance Sleep 会短暂将 Wi-Fi 驱动置于状态 0;任何落入该时间窗的出站 connect() 都可能以 ENETDOWN 失败,即使主机其他方面具有完整网络连接。
  • launchctl print 输出显示 state = not running,并伴随多次最近的 runs 和退出码,尤其是崩溃与下次启动之间的间隔达到小时级而非秒级。macOS launchd 会在崩溃爆发后应用一个未记录的重启保护门控,可能停止遵循 KeepAlive=true,直到交互式登录、仪表盘连接或 launchctl kickstart 等外部触发器重新启用它。

常见特征:

  • error.code 为 ENETDOWN 或同级代码的稳定性捆绑包,调用栈指向 Node net 的 lookupAndConnect / Socket.connect。OpenClaw 2026.5.26 及更新版本将这些归类为无害的临时网络错误,因此它们不再传播到顶层未捕获处理器;如果你使用的是较旧版本,请先升级。
  • 长时间静默期在你连接 Control UI 或 SSH 登录主机的瞬间结束:重新启用 launchd 重启门控的是用户可见的活动,而不是仪表盘对网关所做的任何操作。
  • runs 计数在一天内递增,但 ~/Library/Logs/openclaw/gateway.log 中没有对应的 received SIG*; shutting down 行:正常关闭会记录信号,临时崩溃不会。

处理方法:

  1. 升级网关:如果你运行的是 2026.5.26 之前的版本。升级后,未来的 ENETDOWN 错误会记录为警告,而不是终止进程。
  2. 减少维护睡眠活动:对于打算作为常驻服务器运行的 Mac mini / 桌面主机:
sudo pmset -a sleep 0 disksleep 0 standby 0 powernap 0

这会显著减少但无法完全消除底层驱动抖动。无论这些标志如何,系统仍可能执行一些用于 TCP keepalive 和 mDNS 维护的维护睡眠。

  1. 添加存活看门狗,以便快速捕获未来被 launchd 搁置的崩溃爆发:
# Example launchd-aware liveness check, suitable for a 5-minute cron or LaunchAgent
state=$(launchctl print gui/$UID/ai.openclaw.gateway 2>/dev/null | awk -F'= ' '/state =/ {print $2; exit}')
if [ "$state" != "running" ]; then
  launchctl kickstart -k gui/$UID/ai.openclaw.gateway
fi

重点是外部重新启用重启门控;在 macOS 上,崩溃爆发后仅靠 KeepAlive=true 并不足够。

相关:

macOS launchd 监督循环与重复的 gateway/node LaunchAgents

当 macOS 安装每隔几秒就不断重启、openclaw 健康检查在健康与不可用之间反复切换,并且即使服务看起来正在运行,通道分发仍然停滞时,请使用此方法。

当 ai.openclaw.gateway 和 ai.openclaw.node 两个 LaunchAgents 都处于活动状态,并且各自注入 OPENCLAW_LAUNCHD_LABEL 时,就会发生这种情况。在该状态下,OpenClaw 可能会检测到 launchd 监管,尝试将重启交还给 launchd,并陷入快速的 EADDRINUSE/重生循环,而不是保持一个稳定的 Gateway 进程。

for i in 1 2 3 4; do
  ps aux | grep 'openclaw.*index.js' | grep -v grep | awk '{print $2}'
  sleep 10
done

openclaw gateway status --deep
openclaw node status
launchctl print gui/$UID/ai.openclaw.gateway | grep -E 'state|last exit|runs'
tail -n 80 ~/Library/Logs/openclaw/gateway.log

查找以下迹象:

  • 在 30 秒采样中出现多个 Gateway PID,而不是一个稳定进程。
  • gateway.log 中出现 EADDRINUSE、another gateway instance is already listening 或重复的重启/交接行。
  • 在只应运行一个受管 Gateway 服务的主机上,同时加载了 ~/Library/LaunchAgents/ai.openclaw.gateway.plist 和 ~/Library/LaunchAgents/ai.openclaw.node.plist。

处理方法:

  1. 如果此主机只应运行 Gateway 服务,请通过 OpenClaw 移除受管 node 服务。如果你确实依赖 node 服务来使用远程 node 功能,请跳过此步骤;卸载它会停止此主机上的这些功能:
openclaw node uninstall
  1. 安装一个持久的 Gateway wrapper,在启动 OpenClaw 之前清除继承的 launchd 标记。请使用受支持的 --wrapper 选项;不要编辑 ~/.openclaw/service-env/ 下生成的文件,因为服务重装、更新和 doctor 修复都会重新生成该文件:
mkdir -p ~/.local/bin
cat >~/.local/bin/openclaw-launchd-workaround <<'EOF'
#!/bin/sh
set -eu
unset OPENCLAW_LAUNCHD_LABEL LAUNCH_JOB_LABEL LAUNCH_JOB_NAME XPC_SERVICE_NAME || true
exec openclaw "$@"
EOF
chmod 700 ~/.local/bin/openclaw-launchd-workaround

openclaw gateway install \
  --wrapper ~/.local/bin/openclaw-launchd-workaround \
  --force

gateway install 会在强制重装、更新和 doctor 修复中保留 wrapper 路径。

  1. 验证 Gateway 已稳定并正在提供 RPC 服务,而不仅仅是处于监听状态:
openclaw gateway status --deep --require-rpc

for i in 1 2 3 4; do
  ps aux | grep 'openclaw.*index.js' | grep -v grep | awk '{print $2}'
  sleep 10
done

PID 采样应显示一个稳定进程,而不是不断轮换的一组 PID,并且入站通道分发应恢复。

  1. 升级到修复了底层双 LaunchAgent 循环问题的版本后,移除临时解决方案并重新安装正常的受管服务:
OPENCLAW_WRAPPER= openclaw gateway install --force
rm ~/.local/bin/openclaw-launchd-workaround

相关:

Linux 上的原生中止(SIGABRT)

malloc(): invalid next->prev_inuse (unsorted) 后跟 systemd status=6/ABRT 表示检测到原生堆损坏。它不会指出导致损坏的代码,并且与内核 OOM 终止不同。JavaScript 信号处理器或稳定性捆绑包无法可靠捕获原生 abort()。请在下一次故障之前配置操作系统 core 捕获。

启动日志包含 native runtime(PID、平台、架构、Node、V8、libuv、OpenSSL 和 SQLite 版本)以及 worker startup state(受跟踪的 Worker 数量、按脚本统计的启动/退役次数,以及共享计算准入计数器)。这些是启动时事实,而不是故障发生时刻的快照。请将它们与崩溃时间戳、journal、确切的 OpenClaw 构建版本和 Node 可执行文件一起保留。

对于 systemd 系统服务,请替换下面已安装的单元名称。对于用户服务,请使用不带 sudo 的 systemctl --user;其硬 core 限制不能超过用户管理器继承的限制。

sudo systemctl edit openclaw-gateway.service
# Add this drop-in:
# [Service]
# LimitCORE=infinity

sudo systemctl daemon-reload
sudo systemctl show openclaw-gateway.service -p LimitCORE -p MainPID
sysctl kernel.core_pattern

在下次由运维协调的服务重启时应用该限制。然后检查运行中进程的 /proc/<gateway-pid>/limits 中的 Max core file size;修改单元不会更改已运行进程的限制。

选择 kernel.core_pattern 指示的捕获后端:

  • systemd-coredump: 验证发行版的处理程序已安装并启用。检查 coredump.conf 的存储和大小限制;多 GB 的 Gateway 需要足够的磁盘空间以及 ProcessSizeMax/ExternalSizeMax 来保留其 core。崩溃后,使用 sudo coredumpctl info <crashed-pid> 和 sudo coredumpctl debug <crashed-pid>。
  • Apport: 检查 /var/log/apport.log 和 /var/crash。针对同一 Node 可执行文件/用户的现有报告可能会抑制后续报告。请将那个确切的过期 .crash 报告归档到 /var/crash 之外的仅 root 可访问目录中,然后按照发行版的 Apport 流程清除任何匹配的过期 sidecar。不要删除无关报告。验证 Apport 已启用并且确实接受下一个报告;仅有 code=dumped 并不能证明 core 已保存。
  • 直接 core 文件: 如果已安装的处理程序无法保留此次崩溃,管理员可以临时将其替换为私有绝对路径:
# Record the old value so it can be restored after the investigation.
sysctl kernel.core_pattern
sudo install -d -m 0700 -o <gateway-user> -g <gateway-group> /var/lib/openclaw-cores
sudo sysctl -w 'kernel.core_pattern=/var/lib/openclaw-cores/core.%e.%p.%t'

core_pattern 是主机范围的:这也会替换其他进程的捕获。确保该目录可由 Gateway 服务用户写入,并且在任何服务文件系统沙箱内可访问。捕获完成后恢复之前的 pattern。此临时 sysctl 设置不会在重启后保留。

Validate the chosen backend with a disposable process under equivalent service limits and identity, never by aborting the live Gateway. Open a captured core with the matching Node binary and debug symbols (gdb /path/to/node /path/to/core for direct files), then run thread apply all bt. Preserve all thread stacks: the aborting thread can be detecting damage caused elsewhere. Core files contain process memory, including credentials and message content; keep them private and share only reviewed, redacted evidence.

Gateway 在高内存使用期间退出

当 Gateway 在负载下消失、supervisor 报告 OOM 式重启,或日志显示 memory pressure: level=critical 时使用。

openclaw gateway status --deep
openclaw logs --follow
openclaw gateway stability --bundle latest
openclaw gateway diagnostics export

查找:

  • 带有 reason=rss_threshold、heap_threshold 或 rss_growth 的 memory pressure: level=critical。
  • 该日志行中的 RSS、heap、threshold 和 growth 值。
  • 如果可用,来自致命退出、关闭超时或重启启动失败的现有 stability bundle。

常见特征:

  • Gateway 日志中出现 memory pressure: level=critical → OpenClaw 检测到严重内存压力,并记录了可用的进程内内存事实。
  • reason=heap_threshold → 先降低 prompt/session 压力或减少并发工作。对于托管服务,将 openclaw gateway status 中 Gateway heap: 的配置控制项和安装时推荐值与运行时测量值进行比较。重新安装会保留现有已存储的 heap 设置;它不会自动用当前推荐值替换旧值。
  • reason=rss_growth → RSS 下限在连续采样窗口中持续上升。检查最新日志中是否存在大型导入、失控的工具输出、重复重试或一批排队的 agent 工作。
  • 日志中出现严重内存压力但不存在 bundle → 在事件发生后捕获 openclaw gateway diagnostics export,以获取可用的运维证据。压力事件不会自动写入 bundle。

在 Node 上,管理员还可以使用 openclaw gateway call diagnostics.heapProfile --timeout 30000 采样分配。这会捕获当前分配活动,而不是过去的峰值或所有 native 内存。旧 bundle 仍可通过 openclaw gateway stability --bundle latest 读取。

在将脱敏后的 diagnostics export 附加到 bug 报告之前,请审查它;避免复制原始日志。

Node 的自动 heap 上限在大型主机上可能约为 4 GiB。这是一个默认大小决策,而不是一般的 64 位地址空间上限。--max-old-space-size 控制 V8 old space;测量得到的 V8 heap 总上限还包括其他 heap 空间。RSS 还包括 native 分配、缓冲区和其他进程内存。更高的 heap 上限不会预分配该上限,但在持续负载下仍需要足够的实际容量和余量。

对于前台 Node Gateway,请在 Node 启动前设置 native heap 标志,例如在容量充足的主机上:

NODE_OPTIONS="--max-old-space-size=16384" openclaw gateway run

对于自定义 supervisor 或 Docker 运行时命令,请将 --max-old-space-size=16384 放在 node 之后、OpenClaw 入口脚本之前,或在该进程或容器的启动环境中设置 NODE_OPTIONS。Docker 镜像构建时的 heap 选项不会配置运行时 Gateway。在 Node 启动后加载的 OpenClaw 配置或 dotenv 值无法调整其 heap。NODE_OPTIONS 也可能传递到派生的 Node 子进程,因此当只有 Gateway 应接收该预算时,请优先使用直接的 Node 参数。

对于托管 Node 服务,请使用 托管 Gateway heap 策略,并在更改前检查托管启动参数和由 operator 拥有的环境覆盖项。Native argv 会覆盖 NODE_OPTIONS 中的同一选项;百分比 old-space 大小设置优先于绝对 old-space 大小设置。重新生成会保留已存储的 argv,但当 operator 覆盖拥有 NODE_OPTIONS 时,不会添加自动 heap 标志。安装器 shell 的 NODE_OPTIONS 不会成为服务覆盖项。运行时压力诊断使用有效的 V8 heap 上限以及物理/报告约束余量;过大的显式 heap 设置不会将 RSS 告警阈值提高到物理容量以上。压力警告是诊断证据,而不是 heap 限制或自动重启触发器。

RSS 增长检测比较已完成的五分钟窗口中的最小 RSS 值,并要求连续两次增加。当这些下限持续上升时,增长会累积;持平或下降的下限、超过十分钟的采样间隔或时钟回拨会重置趋势。这可以过滤普通 GC 峰值,同时检测较小的持续增加。日志中的 rssGrowth 和 windowMs 描述累积的下限增加量以及这些最小值之间的经过时间,该时间可能超过十分钟。

在 Node 上,增长警告和严重事件使用测量得到的 V8 heap 上限与可用进程容量中较小者的 4% 和 8%,最低阈值分别为 512 MiB 和 1 GiB。进程容量使用受物理 RAM 限制的已报告约束,或未报告约束时使用物理 RAM。对于 16 GiB heap 且 RAM 充足的情况,这些阈值约为 655 MiB 和 1.28 GiB。未知 heap 限制和 Bun 保留 512 MiB/1 GiB 增长阈值;Bun 现有的绝对内存上限保持不变。绝对 RSS 和 heap 压力检查仍会在每个采样时运行。

相关:

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw