Files
DevFlow/docs/02-架构设计/专项设计/u-relay-运维手册-2026-10-10.md
lxy 8df4e33656 文档: 看板销账与登记 + 设计档六份 + 索引补录
- 看板: 907 补注/909~941 登记与销账(含 929 模型停用根因与 4 处次生缺口、931 队列丢失、933/935/937 新需求、939 上下文瓶颈清单、941 C-r0 行为变更待拍板)
- 归档: 全量完成态条目/段落 + 只读核验销账 4 段迁 todo归档/2026-10-10.md(机械搬运零措辞改动,未完成项零丢失)
- 设计档: 输入框列表预览与自动编号 / 定时消息与待发箱持久化(统一 ai_outbox 底座) / 对话内定时延时任务 / 消息渲染管线重构(P0-P2 分期) / 上下文分层组装器落地方案(记账基点单一真值,与并行写者职责划清) / FileTree 大目录方案(推荐后端分页,否决虚拟滚动) / u-relay 运维手册
- 索引与事实修正: docs/INDEX crate 数 8→13 + 四子树补录 25 条 + 专项设计补录 27 条;纠正「项目无独立 ARCHITECTURE.md」等过时声明;统一 bun 口径
- CLAUDE.md: 新增「命名与代码风格」节(变量/方法名精简+准确;DRY·简洁·扩展性·高内聚低耦合·单一真值来源)
2026-10-10 08:09:25 +08:00

7.2 KiB
Raw Permalink Blame History

u-relay 运维手册(token 轮换 · 一通道一 agent · 心跳约束)

适用:u-relay 跨端中继的日常运维纪律。协议细节见 u-relay Wire 协议规格,本手册只讲运维动作与约束。 来源:协议评估遗留三项(单共享 token 可冒充 / 心跳间隔未定值 / 同 channel 多 agent 全投递)。 本手册不含任何 token 值、主机地址等敏感信息——真值只在部署机 /etc/u-relay.env 与各客户端本地配置里。


1. 心跳间隔约束

心跳间隔须显著小于链路最短空闲超时(反代 proxy_read_timeout,配置样例 300s;生产实时值可能更大), 以容忍连续数次心跳丢失仍不断链。约定 30–60s,各方实现见协议规格 §4.4:

  • Agent(df-tunnel):HEARTBEAT_INTERVAL 常量,30s(WS 协议层 Ping)
  • Commander 参考(u-ppt):30s(应用层 control_kind:"ping")

改反代 proxy_read_timeout 时须同步评估心跳间隔:若把超时压到 300s 以下,间隔也要相应收窄并保持「超时 / 间隔 ≥ 5」量级的余量。


2. 单共享 token 轮换 Runbook

2.1 现状与风险

u-relay 鉴权是单一共享 token(env U_RELAY_TOKEN,服务端常量时间比较),不做 per-channel 隔离: 任何持有该 token 的客户端可声明任意 channel_id 冒充任一通道。故 token 属敏感凭据, 泄露即等于整条中继失守;轮换是唯一的止损手段。

2.2 涉及方与各自持有位置

token 值散落在「服务端 + 多个客户端」,没有集中下发通道:

方 角色 token 持有位置
u-relay 服务端 鉴权源 部署机 /etc/u-relay.env(U_RELAY_TOKEN,权限 600)或 systemd unit 的 Environment=
devflow 桌面端 Agent relay_token 设置项(运行时读,缺省回退硬编码默认值)
devflow 小程序 Commander apps/df-miniapp/src/config.ts 缺省 + 设置页可改
devflow ask_uclaw Commander 设置页 uclaw_token(与 relay token 同源)
u-claw Agent/Runner u-claw 侧配置
u-ppt Commander relay.ts 配置

新增任何接入端都要登记到本表——漏一端的后果见下节。

2.3 锁步成本(务必先读)

因为服务端只认一个 token、客户端各自缓存,轮换天然是一个锁步切换:

  • 无重叠窗口:服务端不能同时接受新旧两个 token,故不存在「灰度换端」的过渡期。
  • 顺序无解:先改服务端 → 全部旧客户端立即 auth_failed 掉线;先改客户端 → 全部客户端在服务端切换前拿新 token 一样 auth_failed。两条路都有中断窗口。
  • 漏端即静默失联:任一客户端未同步换 token,会持续 auth_failed 被拒连,表现为该端静默离线(无业务错误、仅 relay 日志有 auth_failed),排查成本高。
  • 不可逐端滚动:无法像多 token 系统那样「先切一半、观察、再切一半」。

结论:轮换是一次计划内的协调停机,中断窗口 = 从「首个客户端改值」到「服务端重启加载新值」的间隔。执行要点是把客户端改值的动作压到最短、紧接着重启服务端。

2.4 执行步骤

前置:准备好新 token,确认上表每一端都有人能改、改完可验证。

  1. 写服务端新值(先不重启):在部署机把 /etc/u-relay.env(或 unit Environment=)的 U_RELAY_TOKEN 改为新值,保持服务仍在跑旧值。此时新值尚未生效。
  2. 集中改用各客户端:将上表每一端改到新值。此步开始后各端会 auth_failed,中断窗口从这里起算。
  3. 重启服务端加载新值:systemctl restart u-relay。重启后已改端的客户端重连即通。
  4. 验证:见 2.5。
  5. 未改端收尾:对仍 auth_failed 的端补改(此时只有漏改者受影响,不再影响大局)。

若某些端的 token 是编译期硬编码(无运行时配置项),须提前把「新 token + 重新打包」的产物备好,否则第 2 步无法即时完成,窗口会被拉长。

2.5 验证

  • 服务端:systemctl status u-relay 正常,ss -tlnp | grep 9180 在听。
  • 连接:拿新 token 走一次握手冒烟(/ws/agent 或 /ws/commander,收 hello_ack 即通)。
  • 日志:确认无 auth_failed 残留——有则说明还有端没换到新 token。

2.6 回滚

轮换失败(如某端无法改)时,把服务端 env 回退到旧 token 并再重启一次,回到轮换前状态;客户端已改的端随之 auth_failed,需一并回退。回滚与轮换同样是锁步中断。

2.7 根治方向

根治是去掉单共享 token:服务端改为 per-channel / per-client token(客户端拿自己的凭据只能绑自己的 channel), 届时任一端轮换互不影响,锁步成本消失。在此之前,本 runbook 的锁步纪律是必须遵守的现状约束。


3. 运维纪律:一通道一 agent

3.1 现象与根因

u-relay 路由按 channel_id 配对,且同 channel_id 允许多个 agent 并存、命令全投递(Vec 索引,无去重、无选举)。 即:同 channel_id 上跑两个 agent 实例(如两个 devflow 桌面端、或 devflow + u-claw runner 用了同一通道), 一条 commander 指令会被两端各执行一次——写文件、跑命令、调外部接口全部重复,且两端事件回传互相交错。

3.2 危害

  • 指令重复执行:副作用翻倍(重复落库 / 重复发消息 / 重复改文件),且难以察觉。
  • 事件串台:commander 收到两份进度/结果,流式 UI 错乱;两 agent 的上下文互相污染。
  • 隐性化:两端都「看起来正常工作」,问题只在副作用层面暴露,事后才追溯得到。

3.3 纪律

  • 一通道一 agent:每个 channel_id 在任一时刻只允许一个 active agent。通道不是「实例池」。
  • 启动前先查:起第二个 agent 前,确认目标 channel_id 上没有在跑的 agent(换一个独立 channel_id,或用不同通道前缀)。
  • 换装/重启要收尾:旧 agent 若未干净退出(进程被杀但连接残留),WS 连接可能存活到对端超时,期间新旧两连接同通道并存 = 短暂双投递。换装脚本须确认旧连接已断、或等旧连接超时后再起新实例。
  • 命名隔离:不同用途用不同 channel_id(如按机器 / 按项目 / 按用户拆通道),从命名上杜绝复用。

3.4 排查手法

怀疑重复执行时:

  • 看 relay 日志:同一 channel_id 是否同时有 >1 条 agent 连接。
  • 看 commander 侧:同一 request_id 是否收到两份 result / 事件重复。
  • 看副作用:文件 mtime、DB 记录、外部调用日志是否成对出现。

确认后,断开多余 agent 连接(停掉重复实例)即可恢复单投递。


附:关联

  • 协议全貌:u-relay Wire 协议规格(§4 心跳、§5 部署、§3.3 路由)
  • u-relay 仓 README / 部署技能:中继二进制与 systemd 发布流程
  • 看板登记:docs/todo.md「新能力引入评估纪律」下三项 P3