跳转至

重启与监管

重启标志、主机服务由哪个安装拥有、外部监督进程以及性能分析。属于 openclaw gateway 参考的一部分。

重启 Gateway

openclaw gateway restart
openclaw gateway restart --safe
openclaw gateway restart --safe --skip-deferral
openclaw gateway restart --force
openclaw gateway restart --wait 30s

Warning

手动重启信号现在使用 SIGUSR2。SIGUSR1 会启动 Node 的 inspector,并且不再重启 Gateway。请更新发送旧信号的脚本;对于服务感知的重启,优先使用 openclaw gateway restart。

--safe 会请求正在运行的 Gateway 对活动工作执行预检,并在该工作排空后安排一次合并重启。等待时间上限为 5 分钟;当预算到期时,重启将被强制执行。--safe 不能与 --force 或 --wait 组合使用。

--skip-deferral 仅绕过安全重启的活动工作延迟门控。即使报告了活动工作阻塞项,它也可以让 Gateway 进入关闭流程,但在进程退出之前,关闭阶段的待处理回复排空仍然适用。它要求使用 --safe —— 当延迟卡在失控任务上,并且仍允许回复投递完成时,可以使用它。

--wait <duration> 会覆盖普通(非安全)重启的排空预算。接受纯毫秒数或单位后缀 ms、s、m、h、d(例如 30s、5m、1h30m);--wait 0 表示无限期等待。与 --force 或 --safe 不兼容。

原生服务停止截止时间仍然适用:Gateway 将排空时间限制为 315 秒,以适配 systemd 的 330 秒限制;对于 launchd 的 20 秒限制,则限制为 5 秒。两者都为取消和清理留出时间。这些上限同样适用于 --wait 0。更长的模型或心跳超时不会延长它。如果可用,排空日志会报告观察到的最大模型请求超时,作为上下文参考。

如果在 systemd 或 launchd 下,工作仍然在关闭截止时间时忽略取消,那么原生服务停止或由监督进程拥有的重启会记录剩余的工作类别,写入诊断稳定性包,并以状态 0 退出。它不会复用该未完成运行时进行进程内重启。这可以让请求的停止干净地完成,并让服务管理器启动一个全新的 Gateway 用于重启。

显式的服务器关闭失败会保留退出状态 1,包括最终 provider 清理超过原生关闭截止时间时。

准入关闭日志会标明关闭触发器,例如 stop (SIGTERM) 或 restart (SIGUSR2: config reload: gateway.bind)。仅凭信号无法识别其发送者:Node 不会暴露发送者 PID 或命令。在同一进程中,同一信号在五分钟内出现三次,或在进程生命周期中记录到三次普通的 SIGTERM/SIGINT 停止,会生成一条提示,建议检查 openclaw gateway status --deep 以查找另一个监督进程。深度本地状态会显示所选状态目录中最后记录的关闭原因和时间;在 Linux 上,检查原生服务时,它还会报告竞争的用户和系统服务单元。失败结果会保留其具体的失败原因。

降级后,Gateway 会拒绝 schema 比当前运行构建所支持版本更新的数据库。启动错误和 openclaw gateway status --deep 会报告发现的 schema 版本、支持的 schema 版本、已记录时的写入者构建,以及拒绝的构建。请运行一个至少与写入者一样新且支持这些 schema 的构建,或者停止服务并恢复升级前的备份。启动会保留退出状态 78,并在可能时暂停一个受管理的 LaunchAgent。被拒绝的共享状态数据库无法记录新的生命周期行;错误日志会解释拒绝原因,深度状态会报告该情况,而不是不可用的关闭记录。

前台/手动 Gateway、由 OPENCLAW_NO_RESPAWN=1 选择的进程内重启,以及其他监督进程,在清理无法在关闭截止时间前完成时,会保留退出状态 1。

--force 会立即开始重启并关闭新的准入。当前 CLI 会提供正常的排空预算,并受原生服务关闭截止时间限制。只有在该截止时间时仍剩余的工作会在清理前被取消。一个延迟预算已经过期的安全重启不会获得第二次排空预算。普通的 restart 通常使用服务管理器重启路径。

来自较旧调用方、未提供排空预算的强制请求最多有 45 秒进行排空。它们的 60 秒替换窗口为清理预留 10 秒,为替换预留 5 秒。这同样适用于交互式调用方和更新调用方。如果排空到期时仍有工作剩余,Gateway 会在其重启历史和日志中记录一条警告,包含剩余的工作类别,然后通过正常的终端恢复取消该工作。提供预算的调用方会保留该预算,但受原生服务截止时间限制。

在升级期间,重启会在现有 Gateway 状态中记录其原因和排空选项,而不会在旧 Gateway 仍在运行时启动 schema 迁移。如果不存在状态数据库,它会记录意图记录已被跳过,并继续重启。

当更新器调用已安装的 gateway restart 命令时,其现有的更新标记会在观察到受管理进程运行后启用五分钟启动看门狗。这让较旧的更新器无需传递新选项即可完成慢速首跳启动。看门狗包含迁移、监听器和健康阶段;阶段变化不能延长其上限。由较新更新调用方提供的显式就绪预算优先。普通独立重启只有在同一个正在运行的 Gateway 推进启动阶段,或获取、续期或完成一个已观察到的同进程迁移时,才会等待超过标准就绪预算,最长五分钟;随后报告 still-starting(退出码 2),并将最后阶段和 openclaw gateway status --deep 作为下一步;没有进展的启动仍会在标准预算时失败(退出码 1),而一个新观察到的迁移租约在被视为停滞之前会获得一个心跳间隔加上轮询宽限时间,其观察到的完成会在同一上限内获得一个全新的就绪窗口。参见 重启恢复。

在 Windows 上,从 Gateway 服务进程发起的普通重启(包括代理的 shell 命令)会自动使用安全重启路径。正在运行的 Gateway 拥有延迟的计划任务交接,因此停止其进程树不会在重新启动之前杀死调用方。这需要可访问的 Gateway;该命令确认重启请求,而不是验证后继进程的健康状态。之后请使用 openclaw gateway status 验证恢复。

Windows 交接会等待正在退出的 Gateway 退出,然后请求启动任务。只有当一个具有预期可执行文件和 Gateway 入口点的不同进程在配置的端口上监听时,它才会在 logs/gateway-restart.log 中记录 restart finished。此监听器检查最多允许三分钟;它并不能证明通道就绪。仅标记为 Running 的任务或成功的启动请求本身都不算恢复。

如果没有出现替代监听器,日志会记录 restart failed,以及一条包含 profile 信息的 openclaw gateway restart --force 命令,需从外部终端运行。交接不会结束其自身的计划任务:在具有 Job Object 包含机制的安装中,这样做可能会在观察者记录结果之前终止观察者。残留的运行中任务仍可能需要这种外部恢复。

在 macOS 上,当 openclaw gateway restart、stop、install 或 uninstall 在受管 LaunchAgent 的进程树中运行时(包括代理的 shell 命令),OpenClaw 会从 launchd 的服务环境中检测到这一点;或者,当手工编写的 plist 省略这些变量时,会通过与 launchd 为该作业报告的 PID 进行进程祖先关系检测。重启会交接给一个分离的辅助进程,因此 kickstart -k 无法杀死调用方。停止、安装和卸载会拒绝执行,并要求你从外部 shell 运行该命令。

没有 Gateway 服务标记的外部终端、由外部监管的 Gateway、node 服务以及非 Windows 调用方会保留其现有路由。显式的 --force、--wait、--preserve-definition 或 --skip-deferral 也会保留其现有行为和校验;它们不会隐式启用 --safe。

Warning

内联 --password 可能在本地进程列表中暴露。优先使用 --password-file、环境变量,或由 SecretRef 支持的 gateway.auth.password。

安装身份

服务管理(install、start、stop、restart、uninstall、Doctor 服务修复以及自更新服务处理)归属于拥有主机服务的那个安装。即操作系统账户主目录下的规范 .openclaw 目录,或命名 profile 投影到该处的 .openclaw-<profile> 目录。命名 profile 使用不同的原生服务身份。

OPENCLAW_HOME 可以显式选择操作系统账户主目录,包括该主目录的文件系统别名。进程主目录(HOME 或 USERPROFILE)和有效的 OpenClaw 主目录都必须解析到账户主目录。指向其他位置的 OPENCLAW_HOME、OPENCLAW_STATE_DIR 或 OPENCLAW_CONFIG_PATH 会被视为隔离状态并跳过。迁移或复制的状态树不能接管并重写账户的主机服务。

Doctor 还会验证已安装服务中保存的环境。那里的规范 OPENCLAW_HOME 不会阻止 openclaw doctor --fix 进入维护模式并导入旧凭据。Doctor 仍然是迁移负责人:它会验证导入的凭据,并在正常运行时读取恢复之前归档原始字节。

在 macOS 和 Windows 上,由原生服务管理的 profile 名称必须为小写。仅运行时 profile 仍可使用大写,但大小写不同的名称(例如 Main 和 main)在常规不区分大小写的文件系统中会共享路径,无法安全地拥有各自独立的原生服务。在 macOS 上,小写名称 gateway 和 node 也不能用于原生服务管理,因为它们的历史 LaunchAgent 标签与默认 Gateway 和 node-host 服务冲突。

命名 profile 还必须使用从 OPENCLAW_PROFILE 派生的原生服务身份。在执行服务管理之前,取消设置 OPENCLAW_LAUNCHD_LABEL、OPENCLAW_SYSTEMD_UNIT 或 OPENCLAW_WINDOWS_TASK_NAME;自定义身份仍可用于默认 profile 或仅运行时/外部监管配置。

在 Linux 上,发现机制还会识别旧版 openclaw-<profile> 单元名称。当自定义系统单元的 OpenClaw 启动器、服务账户、profile 以及状态/配置路径能够标识该安装时,它可以属于默认安装。发现机制使用 systemd 的有效命令和环境,包括 drop-in 和环境文件。如果多个自定义单元匹配,或包装器使其身份不明确,请使用 OPENCLAW_SYSTEMD_UNIT 指定目标单元;OpenClaw 不会选择第一个带有其标记的单元。

只有当两个管理器的已加载 Gateway 命令都能标识所选账户、profile、状态/配置路径以及匹配的端口选择时,Doctor 才会提供重复用户单元清理。确认后,它会重新检查这些单元。不同或无法验证的身份会保留用户单元。清理只会移除已确认的用户单元,然后报告任何剩余匹配的单元或无法验证的发现;另一个单元需要在后续 Doctor 运行中单独检查和确认。

在 Linux 上,openclaw gateway install --force 在更改配置、身份验证令牌或服务文件之前,会拒绝已密封的 systemd 服务定义,或无法验证其写入权限的定义。错误会保留其 SERVICE_DEFINITION_SEALED 或 SERVICE_DEFINITION_UNKNOWN 前缀,并添加原因标签和下一步操作,而不会打印私有路径、配置、环境变量值或底层检查错误。

对于 [unsafe-permissions],请在本地检查指定的工件类别。服务目录是 ~/.config/systemd/user;在新安装中,其最近的已存在祖先目录可能是 ~/.config。服务状态目录属于所选 profile。请检查目录元数据,而不是文件内容:

ls -ld ~/.config ~/.config/systemd ~/.config/systemd/user

缺少目录在全新安装中是正常现象。确认受影响的路径属于你本人且并非有意共享后,使用 chmod go-w <path> 移除组/其他用户的写权限,然后重试相同的命令。模式 0700 适用于私有目录。不要递归执行 chmod、不要接管系统路径的所有权,也不要使用 sudo/--force 绕过检查。他人拥有的文件和密封挂载需要部署所有者处理;检查失败则需要先恢复文件系统或原生服务管理器的访问权限。

类型级的 service.d 默认配置作为共享只读输入进行检查,不需要写访问权限。root 用户拥有的选定单元和单元特定的 drop-in 配置仍然受到保护。

外部监管程序

仅当另一个进程管理器拥有 Gateway 生命周期时,才设置 OPENCLAW_SUPERVISOR_MODE=external。在此模式下:

  • openclaw gateway restart 保留现有的安全、强制和有限等待行为,同时以已验证正在运行的 Gateway 为目标,而非 launchd、systemd 或任务计划程序。精确锁定的重启交付在该 Gateway 内部运行,因此替换 CLI 不会在旧进程交接之前迁移共享状态。
  • 原生服务的安装、启动、停止和卸载操作将被拒绝,并提示使用外部监管程序。
  • OpenClaw 自我更新将被拒绝,以便监管程序可以停止 Gateway、替换并完成运行时更新,然后安全地重新启动它。
  • 全新进程重启会在干净退出前写入一个有界的 SQLite 交接数据。如果持久化失败,Gateway 会回退到进程内重启,而不是在无可消费交接数据的情况下退出。

外部监管程序还可以声明对共享状态写入的持久所有权:

OPENCLAW_SUPERVISOR_MODE=external \
  openclaw database ownership claim --manager gateway-supervisor --json

在声明之前,停止并验证所有早于 2026.8.1 且可写入共享状态数据库的 Gateway、CLI、Doctor、更新程序和原生应用进程。来自所有权契约 (#121069) 之前的进程不理解所有权行,无法被追溯性隔离。只有在所有剩余写入者都使用支持所有权的代码并携带 OPENCLAW_SUPERVISOR_MODE=external 之后,才能进行声明。

对于相同的稳定管理器标识符,该声明是幂等的,并且会拒绝不同的管理器。不存在自动声明或取消声明的路径。一旦声明,未标记的可写共享状态打开操作将在权限检查、schema 迁移、增量修复、压缩或其他变更之前失败。只读访问仍然可用。这是针对意外的未标记同用户写入者的保护,而非身份验证或租约协议。

对于升级和回滚,让监管程序创建一个无 SQLite 附属文件的合并 WAL 一致性复制快照,然后在激活前运行目标版本自带的 openclaw database preflight <copied-state.sqlite> --json。仅凭数字 schema 版本并不能证明同版本的增量结构是兼容的。参见 数据库 schema。

OPENCLAW_SERVICE_REPAIR_POLICY=external 仍然是一个独立的 Doctor 修复策略。它不声明运行时所有权;需要两种行为的监管程序应同时设置两个变量。

外部监管程序可以通过隐藏的机器契约协商并消费重启交接数据:

openclaw gateway restart-handoff capabilities --json
openclaw gateway restart-handoff consume --expected-pid <pid> --json

协议版本 1 支持 consume 操作。消费操作会在一个即时 SQLite 事务中验证预期的 PID 和有界的交接字段。已接受的交接数据在返回成功之前即被删除,因此并发或重放的消费者无法同时接受它。PID 不匹配的数据会保留给匹配的所有者;缺失、过期和无效的行不会授权重启。

有效的机器请求返回 JSON,退出码为 0,包括非重启结果。无效参数返回 reason: "invalid-expected-pid",退出码为 2;状态存储故障返回 reason: "store-unavailable",退出码为 1。监管程序应在其将要使用的确切运行时或启动器上探测 capabilities,而不是从 OpenClaw 版本字符串推断支持情况,或直接读取私有 SQLite schema。

外部监管程序的实现还应遵循以下验收规则:

  • 为能力探测设置超时,该超时需考虑已部署运行时和存储上完整的 CLI 冷启动延迟,而不是假设热启动的时序。
  • 如果能力协商或交接消费拒绝替换,请立即以非零状态退出,以便进程管理器的恢复策略可以运行。不要在没有任何 Gateway 子进程或监听器的情况下保持存活。
  • 将监管程序进程的存活与替换启动和通道就绪状态区分对待。只有在新的 Gateway 拥有其监听器且 /startupz 返回 status: "started" 后才报告成功;分别监控 /readyz 以了解已配置通道的健康状况,而 /healthz 仅证明存活。

Gateway 性能分析

  • OPENCLAW_GATEWAY_STARTUP_TRACE=1 记录启动期间各阶段的耗时,包括每个阶段的 eventLoopMax 延迟和插件查找表耗时(已安装索引、清单注册表、启动规划、所有者映射工作)。process.bootstrap 分解包括更早的 CLI 导入、配置、数据库准入、会话清单和工作空间就绪。每个引导步骤都记录其相对于进程的 start、持续时间、调用次数和可用的 fleet 计数;重复调用会聚合在同一名称下。ready 跟踪会在 bootstrapSteps 中重复步骤名称和总计。嵌套步骤存在重叠,因此不应将它们的持续时间相加。
  • OPENCLAW_GATEWAY_RESTART_TRACE=1 记录 restart trace: 行,涵盖重启信号处理、活跃工作排空、关闭阶段、下一次启动、就绪时序和内存指标。普通停止也会以 stop.signal.received 和 stop.drain 时序开始新的跟踪。命名的关闭步骤和粗粒度关闭阶段会在等待前发出 .begin,然后在完成时发出持续时间;未配对的 begin 标识已进入但尚未完成的阶段。这些阶段不会单独计时每个嵌套的清理操作。
  • OPENCLAW_DIAGNOSTICS=timeline 配合 OPENCLAW_DIAGNOSTICS_TIMELINE_PATH=<path> 会为外部 QA 测试框架写入尽力而为的 JSONL 启动诊断时间线(等同于配置 diagnostics.flags: ["timeline"];路径仍然仅限环境变量)。添加 OPENCLAW_DIAGNOSTICS_EVENT_LOOP=1 以包含事件循环采样。
  • 先运行 pnpm build,再运行 pnpm test:startup:gateway -- --runs 5 --warmup 1,可针对构建后的 CLI 入口对 Gateway 启动进行基准测试:首个进程输出、/healthz、/readyz、启动跟踪时序、事件循环延迟和插件查找表耗时。
  • 先运行 pnpm build,再运行 pnpm test:restart:gateway -- --case skipChannels --runs 1 --restarts 5,可在 macOS 或 Linux 上对进程内重启进行基准测试(不支持 Windows;重启需要 SIGUSR2)。该测试使用 SIGUSR2,在子进程中启用两个跟踪,并记录下一次 /healthz、下一次 /readyz、停机时间、就绪时序、CPU、RSS 和重启跟踪指标。
  • /healthz 表示存活;/readyz 表示可用就绪状态。将跟踪行和基准测试输出视为所有者归属信号,而不是从单个 span 或样本得出的完整性能结论。

在未启用跟踪的情况下,停止和重启会在第一个排空快照时报告非零的活动工作类别计数,并在仍处于待处理状态时最多每 30 秒报告一次。这些报告会省略任务标识和请求来源;类别可能重叠。普通停止会在拆除前记录 active-work drain settled; beginning server close,包括在排空超时或失败之后。诊断不会更改排空预算或服务管理器的停止截止时间。

客户端断开连接后,交互式设置仍可用于重新连接。Gateway 的停止或重启会在排空工作之前关闭设置提示。已在进行中的设置写入可能会完成,但设置不会在关闭期间等待另一个回答。Gateway 再次启动后,重新打开设置并检查已保存的设置。

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