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或同级代码的稳定性捆绑包,调用栈指向 Nodenet的lookupAndConnect/Socket.connect。OpenClaw2026.5.26及更新版本将这些归类为无害的临时网络错误,因此它们不再传播到顶层未捕获处理器;如果你使用的是较旧版本,请先升级。- 长时间静默期在你连接 Control UI 或 SSH 登录主机的瞬间结束:重新启用 launchd 重启门控的是用户可见的活动,而不是仪表盘对网关所做的任何操作。
runs计数在一天内递增,但~/Library/Logs/openclaw/gateway.log中没有对应的received SIG*; shutting down行:正常关闭会记录信号,临时崩溃不会。
处理方法:
- 升级网关:如果你运行的是
2026.5.26之前的版本。升级后,未来的ENETDOWN错误会记录为警告,而不是终止进程。 - 减少维护睡眠活动:对于打算作为常驻服务器运行的 Mac mini / 桌面主机:
这会显著减少但无法完全消除底层驱动抖动。无论这些标志如何,系统仍可能执行一些用于 TCP keepalive 和 mDNS 维护的维护睡眠。
- 添加存活看门狗,以便快速捕获未来被 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。
处理方法:
- 如果此主机只应运行 Gateway 服务,请通过 OpenClaw 移除受管 node 服务。如果你确实依赖 node 服务来使用远程 node 功能,请跳过此步骤;卸载它会停止此主机上的这些功能:
- 安装一个持久的 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 路径。
- 验证 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,并且入站通道分发应恢复。
- 升级到修复了底层双 LaunchAgent 循环问题的版本后,移除临时解决方案并重新安装正常的受管服务:
相关:
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 标志,例如在容量充足的主机上:
对于自定义 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