07/Documentation
排查持久 agent 故障
持久 agent 未显示或提示 Unreachable:初始检查、各种原因及修复方法、doctor 检查行,以及常见排查场景
实验性功能。 传输协议、SDK 和本页面可能会在后续次要版本中发生变更,该功能也可能被移除。持久 agent 说明了决定其是否保留的标准。
如果 durable agent 未显示、显示为 Unreachable,或者点击后无响应:通过以下三个命令可以找出原因,原因表格和排查案例列表给出了解决方法。问题排查 涵盖了 Collie 的整体排查。
初步检查
按此顺序依次运行这三个命令:
collie durable list
collie doctor
collie logs| 命令 | 针对 durable agent 显示的内容 |
|---|---|
collie durable list | 对应 sources.json 的每个条目各显示一行,并附带正在运行的 bridge 所给出的状态:loaded、not loaded (restart to apply)、refused (<status>) 或 bridge not answering。loaded 表示 bridge 已加载该条目,并不意味着 durable agent 会响应。当 bridge 针对该名称返回 HTTP 400 时,也会显示 not loaded |
collie doctor | 直接查询 durable agent 本身。它会打印 针对 durable agent 的 Doctor 输出行 的各行,并指出未通过的检查项及修复方法 |
collie logs | 每个 durable agent 的启动行、[bridge] program "desk": durable, private socket /run/user/1000/desk/app.sock,以及配置违规时的原因。错误的 sources.json 会打印 [bridge] FATAL:。读取失败时,每次中断会打印一次 [state] poll failed, marking disconnected: <reason>。以 [durable] 开头的行表示版本拒绝、旧版 lead、丢弃的项以及被删除的日志 |
手机端显示的内容较少。durable agent 行显示 Starting 或 Unreachable,且不给出原因。传输协议版本拒绝有专门的提示词 Version mismatch,并在 durable agent 主页上显示警示框。被拒绝的 token 在连接栏中有专属提示。所有其他原因均由 collie doctor 和 collie logs 指明。
原因对照表
当 Collie 无法连接到持久 agent 时,Collie 的其余部分仍会正常启动,且该持久 agent 会显示为无法连接并附带一个原因。
即使持久 agent 是 sources.json 中的条目,原因信息中也会指明环境变量名称。请将 COLLIE_DURABLE_SOCKET 视为该条目的 socket,COLLIE_DURABLE_URL 视为其 url,COLLIE_DURABLE_TOKEN 视为其 token。条目的修复方法在 sources.json 中。仅持久形式的修复方法在 .env 中,然后是 collie restart。
配置违反规则
Collie 会直接报告这些错误,而无需拨号连接持久 agent。位于 sources.json 条目中的规则在网桥启动时也会被拒绝(sources.json 中存在拼写错误)。
| 原因 | 含义与修复方法 |
|---|---|
COLLIE_DURABLE_SOCKET is not set | 仅持久形式缺少套接字路径。请设置该路径,或者设置 URL 及其 token |
COLLIE_DURABLE_SOCKET must be an absolute path | 提供完整路径,以 / 开头 |
COLLIE_DURABLE_SOCKET is longer than 103 bytes | 缩短路径。将其控制在 $XDG_RUNTIME_DIR 以内 |
the private socket transport is not available on Windows; set COLLIE_DURABLE_URL and COLLIE_DURABLE_TOKEN instead | Windows 不支持套接字传输。请使用 URL 和 token |
COLLIE_DURABLE_SOCKET and COLLIE_DURABLE_URL are both set; set the socket, or the URL with its token, not both | 仅持久形式同时获取了两者。请只保留一种传输方式 |
COLLIE_DURABLE_URL is set without COLLIE_DURABLE_TOKEN; the durable agent refuses a caller with no token | 仅持久形式获取了 URL 但缺少 token。请设置 token |
COLLIE_DURABLE_TOKEN is set without COLLIE_DURABLE_URL; a token is only sent to a URL | 仅持久形式获取了 token 但缺少 URL。请设置 URL,或移除该 token |
COLLIE_DURABLE_URL is longer than 2048 bytes | 将 URL 缩短为持久 agent 的基础地址 |
COLLIE_DURABLE_URL is not a URL | 写作 https://host |
COLLIE_DURABLE_URL must start with https:// | 除 https:// 以外的任何 scheme 都会被拒绝。普通的 http:// 在下方有单独的一行 |
COLLIE_DURABLE_URL uses plain http to <host>, so the token would cross the network unencrypted; use https://, or http://127.0.0.1:<port> for wrangler dev | 使用 https://。普通 http 仅用于 127.0.0.1 或带有端口的 localhost |
COLLIE_DURABLE_URL uses plain http on loopback without a port; name the port, for example http://127.0.0.1:8801 | 添加端口 |
COLLIE_DURABLE_URL must not carry a user name or password; the token goes in COLLIE_DURABLE_TOKEN | 从 URL 中移除用户名和密码 |
COLLIE_DURABLE_URL must not carry a query or a fragment | 从 URL 中移除 ? 部分和 # 部分 |
COLLIE_DURABLE_URL names the durable agent's base only; leave out /session/v1, the adapter adds it | 从路径中删除 /session/v1 |
COLLIE_DURABLE_TOKEN is <n> bytes; it must be at least 32 bytes, for example 64 hex characters from openssl rand -hex 32 | 生成更长的 token,并为持久 agent 分配相同的 token |
COLLIE_DURABLE_TOKEN must be printable ASCII with no spaces | 从 token 中移除空格和其他字符 |
COLLIE_DURABLE_TOKEN is longer than 4096 bytes | 如此长的 header 属于配置错误。请使用更短的 token |
持久 agent 未响应,或响应错误
| 原因 | 含义与修复方法 |
|---|---|
no socket at <path> | 该路径下尚无内容。启动持久 agent,或修正路径 |
cannot check <path>: <message> | Collie 无法读取该路径。请使其对您的用户可读 |
socket-not-private: <check> | 遍历路径失败,冒号后的文本指明了具体部分。常见原因见 隐私检查未通过 |
connection refused | 无监听。崩溃的 durable agent 可能会残留其 socket 文件:陈旧的 socket 文件。在 https 上,该 URL 没有监听 |
no answer within <n>ms | durable agent 挂起或处于冷状态。Collie 在 socket 上等待 1000 ms,在 https 上等待 5000 ms |
tls refused: <message> | 该 URL 的证书被拒绝。Collie 没有跳过此检查的开关 |
the host name does not resolve | URL 中的主机名错误,或者您的网络无法访问它 |
token-refused: the durable agent answered 401 或 403 | durable agent 拒绝了 token。durable agent 拒绝了 token |
too-large | durable agent 的应答大小超出了 Collie 的读取限制:hello 为 16 KiB,快照为 4 MiB。请缩减其响应大小 |
incompatible: the durable agent speaks 2..3, this Collie speaks 1..1 | 版本范围不匹配。请更新较旧的一侧。collie doctor 会显示这两个范围,日志中每个范围记录一行 |
incompatible: not a durable agent | 其他程序在该路径或 URL 上作出了应答。请将配置项指向 durable agent |
incompatible: the durable agent asks for a token | socket 上的 durable agent 需要 token,但 socket 从不携带 token。请更新较旧的一侧,或通过带 token 的 URL 访问它 |
unreadable hello: <detail> 或 unreadable snapshot: <detail> | durable agent 发送了传输协议不允许的文档。请查看该 durable agent 自己的日志 |
the durable agent answered <status> 或 the durable agent answered 409 <code> | durable agent 返回了传输协议在此处不使用的状态码。请查看该 durable agent 自己的日志 |
starting | durable agent 已启动并指示其尚未就绪,或返回了 503。Collie 会在下次轮询时重试 |
针对 durable agent 的 Doctor 输出行
collie doctor 会向每个 durable agent 询问 bridge 所询问的相同问题,并按 bridge 提问的顺序进行。它除了 hello 外不发送任何内容。
sources.json 的每个配置项包含一个由六行组成的区块,对于名为 desk 的 durable agent 显示为 durable-socket:desk。区块前有一行 sources 检查文件,区块后有一行 durable-lead。仅运行 durable 的 Collie 会打印没有后缀的相同六行,其 mux 行显示为 durable, see the durable-* lines。
| 行 | 绿色 | 警告或红色 |
|---|---|---|
sources | 2 durable agents in <path>, mode 0600 | 当文件解析失败时为红色。其修复提示说明在配置错误期间 bridge 不会启动。当属组或其他用户可读该文件时为红色,并以 chmod 600 作为修复建议,因为配置项可能包含 token |
durable-env | 包含路径的 transport: private socket,或 transport: https with a bearer token | 当配置违反来自 原因表 的规则时为红色 |
durable-socket | 路径为一个 socket,属于您,权限模式为 0600,位于属于您的模式为 0700 的文件夹中,路径中不包含链接 | 红色,且该行会指出失败的检查项:不存在、不可读、不是 socket、是符号链接、不是文件夹、属于其他所有者的文件夹、权限模式错误的文件夹、上层文件夹其他用户可写、属于其他所有者的 socket,或权限开放的 socket。在 https 后端的 durable agent 上会跳过 |
durable-url | 地址,https 或 loopback http,及其字节长度 | 当 URL 违反规则时为红色。在 socket 上跳过 |
durable-token | set, <n> bytes。Collie 从不打印该值 | 当 token 违反规则时为红色。在 socket 上跳过 |
durable-hello | durable agent 已应答。两个范围,以及它们协商一致的版本 | 红色并带有原因:token 被拒绝、无响应、响应者不是 durable agent、durable agent 在 socket 上请求 token、不可读的 hello,或者范围不匹配。范围不匹配会同时显示两个范围 |
durable-ready | ready、durable agent 的主机名及其 epoch | durable agent 报告其尚未就绪时的警告 |
durable-lead | lead 足够新,可以显示问题卡片 | 参见 在 crew 中 |
失败的行会阻止其后的行。它们会以原因 fix the row above first 显示为跳过,因为 Collie 绝不会通过未通过隐私检查的 socket 或使用违反规则的 token 向 durable agent 发送请求。跳过的行不是故障。
案例
每个案例都会说明你看到的内容、原因以及解决方法。
sources.json 中存在拼写错误
你看到 Collie 停止运行,而不仅仅是一个 durable agent:手机无法连接。collie logs 以 [bridge] FATAL:、文件路径、条目和字段结尾。
网桥在启动时读取 sources.json,并在遇到未知字段、非 durable 的 kind、违反规则的名称、重复使用的名称、同时出现 socket 和 url、两者皆无、缺少 token 的 url 或带有 socket 的 token 时停止。修复文件,然后运行 collie restart。collie doctor 在其 sources 行中显示相同的消息。
在网桥无法命名条目的情况下(它不是对象、包含未知字段或名称违反规则),它从 0 开始计数,并为第二个条目写入 entry 1。collie durable attach 从 1 开始计数,并为同一条目写入 entry 2。两者都会指出具体的字段。一旦名称有效,网桥就会写入该名称:entry "desk"。
attach 和 detach 拒绝写入无法读取的文件,因此拼写错误绝不会影响其他条目。它们以退出代码 1 停止。
执行 attach 后未出现 durable agent
你在手机上看不到 durable agent,并且 collie durable list 显示 not loaded (restart to apply)。
attach 和 detach 仅写入 sources.json。网桥在启动时读取它。运行 collie restart,或者下次向动词添加 --restart。当 not loaded 在重启后依然存在时,请阅读 collie logs:list 将来自网桥的 HTTP 400 表述为与 404 相同。
隐私检查未通过
你看到 socket-not-private: the socket's folder /tmp/hello has mode 0755, not 0700,并且 doctor 行 durable-socket 为红色。
Collie 仅在整个路径均为私有时才会连接 socket。常见原因是权限模式为 0755 的文件夹、直接位于 /tmp 或其他共享文件夹中的 socket,以及路径中的符号链接。符号链接很容易被忽略:在许多 Linux 主机上,/var/run 会链接到 /run,因此以 /var/run/ 开头的路径会失败并报错 /var/run is a symlink。请使用真实路径。
在 socket 所在的文件夹上运行 chmod 700,或者将 socket 移动到 $XDG_RUNTIME_DIR 下。规则位于 持久 agent 的安全性 中。使用 SDK 构建的 durable agent 拒绝在权限模式不是 0700 的现有文件夹中启动,并会自行输出该提示。
陈旧的 socket 文件
你在 socket 上看到 connection refused,并且该文件存在。
发生崩溃的 durable agent 会留下其 socket 文件,且没有进程在其上监听。重新启动 durable agent。SDK 会在监听前删除失效的 socket 文件,并在 socket 处于活动状态时停止并报错 another instance is already listening。仅当 durable agent 未清除该文件时,才手动删除它。
与终端会话同名的名称
你看到网桥在启动时停止并报错 the name is the terminal session's own; pick another,或者手机上缺少终端会话。
durable agent 不能采用运行 Collie 的终端的名称。在大多数安装中该名称是 default,而在纯 durable 模式的 Collie 上,default 属于其 durable agent。网桥在启动时停止并指出该条目。Herdr 会话与 durable agent 同名是另一种情况:durable agent 保留该名称,手机不显示该会话,并且日志会记录一次。请重命名其中之一。
一直存在的 durable-ready 警告
在每次运行 collie doctor 时你都会看到警告 durable-ready。
durable agent 返回 hello 并报告 ready: false。手机将其显示为 Starting。durable agent 仅在整理好其对话并重新提出待决问题后才会报告已就绪。查看 durable agent 自身的日志以了解它正在等待什么。
durable agent 在启动时因子进程检查而停止
你看到 durable agent 在启动时停止并显示 the descendant check needs Bun on Linux to read the peer of a socket; pass callerCheck: "off" to run without it。
该检查在 Linux 上需要 Bun。在 macOS 上,请使用 Node 运行 durable agent,或者向 openCollie 传递 callerCheck: "off" 并先阅读 该检查保护的内容。错误来自 durable agent。与 Collie 无关。
重启后问题重新出现
durable agent 重启后,你再次看到某个问题,或者看到一张显示该问题已被回答的卡片。
重启前提出问题的答案会收到 too-late,卡片会提示该状态并消失。如果 durable agent 从其工具调用中派生问题 id,它会再次提出相同的问题,因此跨重启发送的答案能够送达,工具只运行一次。每次都生成新 id 的 durable agent 会针对同一个工具调用提出新问题。卡片会显示它,并且 Collie 不会发送第二次推送,因为推送保护基于工具调用进行去重。该保护机制还限制每个对话每分钟 3 次推送,每台主机每分钟 10 次,每台主机每小时 30 次。一小时内的第 31 次推送会转为该主机的一条汇总推送,在此后的一小时内该主机不再发送推送。卡片始终会显示。
403 caller-refused
你看到手机提示答案或消息被拒绝,durable agent 给出的原因是 403 caller-refused。
durable agent 的后代进程检查拒绝了调用方。它会拒绝 durable agent 本身、durable agent 启动的任何进程,以及无法与它们区分的调用方。当 durable agent 或其运行的工具启动了 Collie 进程且该进程仍是其子进程时,Collie 会被归入 durable agent 一侧。请从 durable agent 外部启动 Collie,然后重试。
重试,以及可能已生效的答案
你看到“不确定答案是否已送达”以及一个重试按钮,点击后显示“可能已生效。请查看聊天。”
答案发送后发生超时、连接断开或返回 5xx,意味着它可能已经送达。点击重试会发送相同的请求 id,因此 durable agent 会返回 replayed,绝不会对同一问题解析两次。如果问题已经关闭,第一次尝试可能就已经将其关闭,因此手机会提示查看聊天。发送、停止和按钮点击也都会用各自的文案提示相同的情况。
durable agent 拒绝了 token
你看到连接栏显示“durable agent 拒绝了该令牌。请检查此对等节点上的 COLLIE_DURABLE_TOKEN。”,原因为 token-refused。
durable agent 针对该令牌返回了 401 或 403。最常见的原因是轮换时其中一端先发生了变更。即使对于 sources.json 条目,手机上的文案也会显示 COLLIE_DURABLE_TOKEN:请将其理解为该条目的 token。在重启 Collie 之前,请先为 durable agent 提供新令牌。Token 包含轮换步骤。403 也可能来自 durable agent 前面的访问代理。
需要两次读取才会切换为 Unreachable
你看到 durable agent 在一次读取失败时保持 Ready,随后切换为 Unreachable。
在一次成功的读取之后发生单次读取失败,该轮轮询会保留上一次的布局。连续第二次失败才会切换 durable agent 的状态。被拒绝的令牌也遵循相同规则。未通过隐私检查的套接字路径是唯一的例外:它会立即显示。
在 https 上,处于停机状态或拒绝令牌的 durable agent 最多每 10 秒被请求一次,因为每次尝试都是计费请求。在套接字上,对停机的 durable agent 进行两次读取之间的最小间隔为 250 毫秒。
在 crew 中
crew 成员上的 durable agent 会显示在 lead 的手机上,因此 lead 需要了解什么是 durable agent。
低于 1.21.0 版本的 lead 列出 durable agent 的对话时不会显示问题卡片,其 Terminal 标签页会轮询一个没有终端的对话。成员端无法修复此问题。成员自身会提示该情况:collie doctor 在 durable-lead 中发出警告,并且每收到一个版本信息,日志就会记录一行 [durable] the lead is 1.20.1; it shows durable panes without the question card and its Terminal tab polls; update the lead。请更新 lead。
durable-lead | 提示内容 |
|---|---|
| 已跳过,无 crew | 此机器不在 crew 中,因此没有 lead |
| 已跳过,lead | 此机器是 lead,显示其自身的窗格 |
| 已跳过,无版本 | lead 未声明版本:开发构建、正在更新,或自网桥启动以来未收到调用 |
| 警告 | lead 运行的版本低于 1.21.0 |
| 绿色 | lead 版本为 1.21.0 或更高 |
版本低于 lead 的成员会出现相反的故障。手机提示“此机器运行的 Collie 版本较旧,无法在此接收答案。请更新它,或在 durable agent 中回答。”请更新该成员。