Skip to content

fix: 重跑批量注册时先问 hub 缓存的 token 是否还有效 - #25

Merged
stqfdyr merged 5 commits into
mainfrom
fix/stale-register-token
Sep 19, 2026
Merged

stqfdyr merged 5 commits into
mainfrom
fix/stale-register-token

Conversation

@stqfdyr

@stqfdyr stqfdyr commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

改了什么

重跑批量注册时,由 hub 判断机器上已有的 token 是否还有效

安装器原先只看 agent.env:只要 hub 地址一致、token 在,就直接沿用,不再请求 hub。节点在面板里删掉、或 token 换发之后,在那台机器上重跑批量注册命令,安装器会留着作废的 token 并报告安装成功,agent 随后一直被拒(401)。

  • install.sh:把机器已有的 token 放在 X-Node-Token 头里,随注册请求一起发出(没有 token 时 curl 不发这个头)
  • /api/agent/register:X-Node-Token 仍对应一个节点时原样返回,不建新节点,也不要求窗口开着,所以窗口关闭后重跑照旧成功;对应不上时按常规流程注册,窗口关着就拒绝
  • 这一步排在 HTTPS 入口检查与 IP 锁定之后、窗口与 key 之前:它不创建任何东西,只返回调用方已经持有的 token(agent 握手的 401 本来就能说明 token 是否有效)。查库出错直接返回错误,不会当作「没有节点」而注册出重复节点
  • 安装器提示:请求前显示 registering …;hub 拒绝时原样打印状态码和 hub 自己给出的原因。关窗与 key 错误(同一个答复)、地址被锁(429)、入口不是 HTTPS 域名(403)、数据库出错(500)各不相同,原来 curl -f 把它们都变成退出码 22、一律解释成「key 被拒」。关窗与额度用完两种拒绝,hub 在原因里直接带上「去面板开新窗口」,安装器不按原文匹配;反代或 CDN 回的是整页 HTML 时只打印第一行(截到 500 字节,hub 最长的原因 341 字节),用 printf 输出,dash 的 echo 会解释反斜杠;没收到响应的失败只留 curl 自己的报错;hub 返回空 token 按失败处理
  • hub 分不清「节点被删」与「token 被换发」:两种情况下重跑批量命令都会注册成新节点。安装器此时提示「如果是换发 token,去面板删掉旧节点」;文档说明换发后应使用该节点自己的安装命令重装

上界

单次请求:最多一次按 token 唯一索引的查询、两次设置读取、一次 COUNT、一个小事务;不出网。在飞数不设闸门,与 agent 握手的 token 查询一致;被锁的地址不碰数据库。

实测(release 构建,三核,窗口关闭以免触发锁定):120 个并发请求压注册接口时,面板 /api/nodes 的中位数从 1.1 ms 升到 2.1–2.8 ms,带不带 X-Node-Token 没有差别。

兼容

验证

  • cargo fmt --check、cargo clippy --all-targets -- -D warnings、cargo test(109 个)通过
  • 新增 a_rerun_keeps_its_node_until_the_node_is_deleted;分别让「查到节点」不返回、让「查不到节点」也原样返回,测试都会失败
  • 响应解析(正文与状态码分行)在 dash 与 busybox ash 下,对 200、403(关窗 / 额度用完)、429、500、502 的 HTML、带反斜杠的正文、空 token、连接被拒逐一确认
  • 端到端(开发版 hub + TLS 反代,systemd 容器执行面板给出的批量注册命令):
场景 结果
首次注册(无 agent.env) 注册新节点
窗口开着时重跑 沿用原 token,节点数不变
窗口关闭后重跑 沿用原 token,节点数不变
节点删除后、窗口关着时重跑 退出码 1,给出 key 被拒的原因,并提示原 token 可能已失效
节点删除后、窗口开着时重跑 注册新节点,拿到新 token
token 换发后、窗口开着时重跑 注册新节点,提示去面板删掉旧节点;旧节点仍在面板
注册请求被断开(非 HTTP 错误),机器持有 token 退出码 1,只显示 curl 的 Empty reply from server

失败提示改为显示 hub 的原因之后,经 HTTPS 域名入口对开发版 hub 重跑:

场景 结果
窗口关着、没有 token 退出码 1:registration failed (HTTP 403): registration is closed; open a new window from the panel's node list
窗口关着、持有有效 token 沿用原 token
窗口关着、持有作废 token 同第一行,另提示原 token 可能已失效
窗口开着、key 正确 注册新节点
窗口开着、key 错五次后第六次 退出码 1:registration failed (HTTP 429): too many attempts, try again later
从 IP 入口注册 退出码 1:打印 hub 的「请通过 HTTPS 域名访问面板……」原文

文档的配套修改是 monitor-probe/monitor-document#7,等本 PR 发版后再合并。

安装器原先只看 agent.env:同一个 hub 的 token 在就直接沿用、不再请求 hub。节点在面板里
删掉或 token 换发后,重跑批量注册命令会留着作废的 token 并报告成功,agent 一直 401。

- install.sh:把机器已有的 token 放在 X-Node-Token 头里随注册请求一起发,由 hub 判断
- /api/agent/register:该 token 仍对应节点时原样返回,不建新节点,也不要求窗口开着,
  窗口关闭后重跑照旧成功;对应不上时按常规注册,窗口关着就拒绝
- 新增 a_rerun_keeps_its_node_until_the_node_is_deleted
- /api/agent/register:已有 token 的查询挪到 HTTPS 入口检查与 IP 锁定之后,仍在窗口与
  key 之前;查库出错直接返回错误,不再当作「没有节点」继续注册出重复节点。注释写明单次
  与在飞上界,附 120 并发实测
- install.sh:请求前恢复 registering 提示;只有 hub 回 HTTP 错误码时才解释原因,其他失败
  只留 curl 自己的报错;hub 返回空 token 按失败处理;token 换发后注册成新节点时提示删掉旧节点
- 测试按实际行为改为不带请求头:curl 遇到空值的 -H 不发送该头
curl -f 把关窗、key 错误、地址被锁(429)、入口不是 HTTPS 域名(403)和数据库出错(500)
都报成同一个退出码 22,安装器原来一律解释成「key 被拒,去面板开新窗口」,并丢掉了 hub 写在
响应体里的原因。现在按状态码判断,原样打印 hub 的原因;只有 registration is closed 时才提示
开新窗口。没收到响应的失败仍只留 curl 自己的报错。
- 反代或 CDN 在前时,失败的响应可能是一整页 HTML,原样打印会淹没状态码。改为只取第一行、
  截到 500 字节(hub 最长的原因 341 字节),并用 printf 输出,dash 的 echo 会解释反斜杠。
- this window has registered enough nodes 与 registration is closed 的办法相同,都提示去面板开新窗口。
安装器本来就原样打印 hub 的原因,提示放在 hub 那句话里,两边就不用约定同一段英文。
key 错误与窗口关闭仍是同一个答复。
@stqfdyr
stqfdyr merged commit 6ce9ab8 into main Sep 19, 2026
1 check passed
@stqfdyr
stqfdyr deleted the fix/stale-register-token branch September 19, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant