Files

196 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# XTRH 总控、采集转发与多机节点
这是接入 PXHJ 正式试验流程的系统融合软件,包含 Java 后台服务和独立的只读监测页面。PXHJ 负责试验组织和业务控制;本软件通过 `/console/` 按装备查看真实采集数据,并保留同步质量、虚拟装备、融合视频、融合指标及节点状态的查看入口。未接入的指标和功能显示空状态,不提供演示数据。
采集页面复用 PXHJ 已完成解密、校验、冻结装备绑定及质量判定的数据,经现有服务签名通道全量同步;不增加 UDP 接收器,不修改采集器配置。使用方式和接入边界见 [系统融合软件页面与采集接入](docs/系统融合软件页面与采集接入.md)。主节点部署更新后,可双击 `启动系统融合软件.cmd` 打开页面,默认地址为 `http://127.0.0.1:18100/console/`。
底层原有演示视频任务仍用于独立验证节点调度、迁移和 PXHJ 播放链路,不作为新页面的融合视频源。采集器上传地址协商和节点原图接入已实现;仿真数据协议、仿真目标接入、图像融合和录制尚未实现。
同一个 JAR 通过配置运行三种角色:
| 角色 | 功能 | 安装脚本默认 HTTP 端口 |
|---|---|---:|
| `coordinator` | 总控并默认兼任执行节点,保存上下文与路由、分配任务、处理本机视频、汇总播放地址 | 18100 |
| `gateway` | 接收采集器原始 UDP 字节,按登记来源转发,反向转送 PXHJ 的回执 | 18110 |
| `worker` | 自动发现并注册到总控,领取多个任务,接收原图或生成演示视频 | 18120 |
采集网关的默认 UDP 入口是 `19002`。PXHJ 的现有采集入口 `19001` 保留;同机部署时两个接收端口必须不同。每个采集器使用一个固定 UDP 转发源端口,PXHJ 中对应采集器的可信来源也必须同步更新。
总控的控制与执行在**同一个 Java 进程、同一个 18100 端口、同一个稳定身份**中运行,不需要再为主电脑启动额外 worker 进程。主节点默认容量 2 路,普通子节点仍可部署在其他电脑。总控快照用 `nodeRole=COORDINATOR` 标识主节点、`WORKER` 标识子节点,PXHJ 可统一配置两种节点的路数。
## 已实现的运行规则
- 工作者启动后通过局域网 mDNS 发现同集群总控,认证后自动注册,不需手动添加节点。
- 主执行节点等待自身 HTTP 端口就绪,签名校验自家总控后自动注册;同一主身份不会重复登记成普通子节点。
- 每个部署目录持久保存节点身份;重启不会产生重复节点,启动会话变化会使旧回执失效。
- 每台节点的容量为 0~64 路,PXHJ 可以调整;总控把准备任务也计入容量,超额任务等待。
- 动态迁移先准备新节点,待新画面可用后切换播放地址;无空余容量时保留原输出并报告等待调整。
- 任务来自 PXHJ 保存的试验、装备绑定和真实轮次;轮次结束撤销该轮任务,UDP 转发独立持续运行。
- 总控使用 H2 持久化。总控重启后提高调度代次、撤销旧许可,等待 PXHJ 重新确认上下文。
- 节点心跳失联后任务许可到期;页面不会永久保留失效播放地址。
- 内部 HTTP 请求和响应使用共享凭证生成 HMAC 签名,含时间和一次性随机数校验;发现到的候选地址不会收到明文凭证。
- UDP 原始字节不改变,不依赖报文文本或自造标记。未知/歧义来源丢弃,队列和内存有上限。
- 网关保存最后确认的路由;总控暂时失联或网关重启后继续按这些路由转发。
- 原图接入在试验准备时就可建立,不依赖正式轮次开始;采集器通过网关协商后直接上传接收节点。
- 原图迁移先发布新旧两个目标,等新节点收到完整首帧才切换 PXHJ 取图;许可到期回退原图片上传地址。
当前调度依据 PXHJ 配置的容量和节点在线状态,不会测量 CPU/GPU 负载后自动修改容量。网关现阶段按采集器来源转发不透明字节,正式协议解析仍由 PXHJ 完成;网关内的数据解析、装备状态标准化、订阅分发和独立图片分片组装尚未实现。
图片由执行节点认证和组装,网关只转发协商。接入流程、配置和边界见 [图片直传协商与准备取图](docs/图片直传协商与准备取图.md)。原图接入与演示任务各计一路;新部署的协商开关默认关闭。本次已按授权为 RK3588 开启协商,实际部署与联调见 [开发板记录](docs/开发板图片协商联调记录.md)。
## 代码结构
按业务划分包,控制层只负责 HTTP 转接,服务层处理任务和网络业务,DAO 层只负责持久化。
| 业务包 | 当前主要类与职责 |
|---|---|
| `control.controller` / `control.service` | `CoordinatorController` 接口转接,`CoordinatorService` 节点、上下文、任务、容量和版本调度 |
| `gateway.controller` / `gateway.service` | `GatewayController` 网关状态接口,`GatewayService` 双向原字节 UDP、路由应用和统计 |
| `node.controller` / `node.service` / `node.config` | 媒体和原图接口、任务执行与图片认证重组、主/子执行能力与播放线程配置 |
| `discovery.service` / `discovery.util` | `Discovery`、`CoordinatorLocator` 发现与总控身份核验,`NodeAddress` 对外地址选择 |
| `communication.client` / `communication.security` | `PeerClient` 签名 HTTP 通信,`Signatures` 与 `ServiceSecurity` 签名和防重放 |
| `common.config` / `common.controller` / `common.dao` / `common.util` | `Settings`、健康和错误接口、`StateStore` H2 持久化、`NodeIdentityDao` 身份文件持久化与 `Jsons` 公共辅助 |
应用入口为 `com.xtrh.Application`。测试也放在对应业务的 `service`、`security` 或 `client` 包中。节点会话、限时许可、任务切换、路由缓存及签名校验等关键逻辑保留中文注释。
`StateStore.open(Path, ObjectMapper)` 在 DAO 内统一组装文件数据库地址,业务服务只指定本角色的数据文件;`NodeIdentityDao` 自动生成并复用部署实例身份,配置层不再直接维护身份文件。发现服务的广播只提供地址线索;逻辑总控冲突在远端签名认证后按 `serviceId` 判断,同一总控的多个网卡地址不会算成多个总控。
注释比例按 `scripts/Measure-Comments.ps1` 统计:分母为 Java 非空源码行,分子为以注释标记开头的完整注释行,包含 Javadoc 和块注释边界,代码末尾的行内注释不计入。当前全部 XTRH 主 Java 源码为 **21.53%(594/2759)**,PXHJ 新增 `fusion` 业务源码为 **28.83%(501/1738)**。
PXHJ 的新增业务同样采用 `fusion.controller`、`fusion.service`、`fusion.dao`、`fusion.config`、`fusion.security` 分层,`FusionDao` 承接 SQL,接口、业务和数据访问职责分开。
## 构建和测试
要求 Java 17 或更新版本、Maven 3.9。Windows 示例:
```powershell
.\scripts\Build-Xtrh.ps1 -JavaHome 'C:\Program Files\Java\jdk-25.0.2' -MavenPath 'D:\software\apache-maven-3.9.16\bin\mvn.cmd'
```
产物为 `target/xtrh-services-1.0.0.jar`。脚本先执行测试,测试失败不会返回成功。
`CoordinatorTest` 验证容量预留、超额等待、迁移准备和正式切换、容量不足保留输出、会话/版本隔离、轮次结束、离线租约及总控重启后的上下文确认。`GatewayTest` 使用真实 UDP 套接字验证二进制字节保持、固定转发源端口、反向回复、未知来源拒绝、总控失联及路由恢复。`ServiceSecurityTest` 和 `PeerClientTest` 验证请求篡改、重放、过期请求、伪造响应及凭证不出现在 HTTP 头中。这些是本机自动化验证,不能替代多台物理电脑、真实采集器与网络环境验收。
增加主节点执行能力后,XTRH 全部 **24 项测试通过**:原有 19 项,加 4 项角色能力条件与 1 项随机端口主进程执行集成测试。后者真实读取主端口 JPEG,检查自动注册、唯一主身份、任务就绪及结束撤销。上一阶段 PXHJ 融合后端 17 项和 1 项真实业务串联测试通过;业务串联使用真实 Spring 业务服务、正式接口层登录会话和 CSRF、隔离 H2,连接实际总控和两个子节点,验证保存绑定、动态迁移和正式轮次操作。真实 UDP 加密数据、心跳认证及中转配置回程也有针对性测试。详细范围见 [本机验证记录](docs/本机验证记录.md)。
PXHJ 全后端回归和打包已完成:报告总计 392 项测试,失败 0、错误 0、跳过 30 项;跳过项包含默认不启用的实时外部服务和达梦环境测试,前述真实业务串联已另外显式运行。独立构建输出位于 `runtime/pxhj-build`,新版后端产物为 [pxhj-server-0.1.0.jar](E:/Codex/xtrh/runtime/pxhj-build/pxhj-server-0.1.0.jar)。
本机多进程验证不替代多台物理电脑、真实采集器或真实融合的现场验收;上述 H2 业务串联也不代表已升级正在运行的达梦主实例。
## 开发板图片直传联调(2026-10-15)
已在 `192.168.7.165` RK3588 构建、部署完整 ARM 程序并开启协商,真实 PXHJ 准备页面已经取得节点原图。板上保留原采集功能、原启动器和程序内 1 GiB 日志预算。主、A、B 对外图片地址均为 `192.168.7.222`,当前容量 2/3/3。视频源是已有文件经 RTP 输入开发板,尚未进行真实摄像机或物理多机验收。
联调同时修复了公开帧号被节点近期缓存淘汰后取图 404:PXHJ 先取得验签通过的完整 JPEG,才发布公开编号;短期快照限制 30 秒、4096 张和 64 MiB,预算不足可提前淘汰。后端完整测试 **411 项,失败 0、错误 0、跳过 30**,修复版已加载;详细实测与迁移状态见 [开发板图片协商联调记录](docs/开发板图片协商联调记录.md)。
主节点到 A、A 到 B 两次实际原图迁移均完成。修复后的 A 到 B 页面窗口 45/45 次取得新图,浏览器 HTTP 错误为 0;旧 A 私有许可撤销后,已公布的原图编号仍可返回相同字节。当前由 B 接收原图,节点容量已恢复 2/3/3,现有准备轮次、运行轮次和冻结绑定前后核对一致。
### 板上部署前的软件验证记录
上传地址协商、节点原图接收与 PXHJ 准备取图代理已经实现,本机四个 XTRH 实例及 PXHJ 后端已加载新版。执行节点仍自动注册,主节点也接收原图;图片 UDP 入口实际为 19100、19120、19121,原 PXHJ 6020 保留作回退。三个执行实例在同一台电脑上,物理多机验收尚未进行。
本次完整测试:XTRH 38 项全部通过;PXHJ 后端 403 项,失败和错误均为 0,跳过 30 项;嵌入式独立 Qt 验证 7 个业务用例通过,另含 init/cleanup 共 9 项,实际 C++ 与 PXHJ Java WireCodec 双向加解密通过。PXHJ 构建产物在 `runtime/pxhj-image-build`。前端构建及融合页面既有交互回归通过,页面将原图与演示画面明确区分。
当前全部 XTRH Java 主源码注释 **21.53%(594/2759)**,PXHJ `fusion` 主源码 **29.46%(476/1616)**。图片许可及缓存为短期内存状态,设备密钥不会持久化。
该轮软件部署后只读确认三个执行节点、一个网关在线,PXHJ 达梦缓存已同步,运行轮次数在升级前后均为 1。当时尚未构建和部署目标 ARM 板;后续板上部署已完成,见本节上方最新记录。流程和启用配置见 [图片直传协商与准备取图](docs/图片直传协商与准备取图.md)。
## 上一阶段本机部署记录(2026-10-14)
主总控执行能力版本已部署:`runtime/coordinator` 在 HTTP 18100 同时控制和执行,主节点容量 2;`runtime/gateway` HTTP 18110 / UDP 19002;子节点 A HTTP 18120 / 容量 2,B HTTP 18121 / 容量 3。只读签名快照确认 **3 个在线执行节点、1 个在线网关,总容量 7 路**;主节点只有一条 `COORDINATOR` 记录,身份与总控一致,子节点为 `WORKER`。子节点和网关未手工配置总控 URL。
PXHJ 达梦主后端已通过私有连接配置接入总控。本次主节点执行能力升级只重启了 18100 主进程,保持原稳定身份、数据目录和配置;PXHJ 后端、前端、网关和两个子节点均未再次重启。实际 `biz_fusion_cache` 已自动更新为三个在线执行节点和一个在线网关,检查时缓存年龄 64 毫秒。PXHJ UDP 19001、图片 UDP 6020 与网关 UDP 19002 持续运行。
原有一轮 `RUNNING` 保持运行,没有自动结束或修改现有试验;未给该正式试验新增演示视频配置,真实采集器上传地址和接收路径也未切换。前端进程持续运行。用户可在 PXHJ 的融合节点管理和试验组织中的节点/视频区域统一操作。隔离验证的四个 182xx 实例已按身份停止,默认端口的四个新角色继续在线。
当前主、子节点均没有正式视频任务运行,实际主端口 JPEG 已在隔离随机端口集成测试中验证;未为证明功能而操作正在运行的正式试验。
## 部署
### 1. 为同一个集群生成一次私有凭证
```powershell
.\scripts\New-ClusterCredential.ps1 -CredentialFile 'E:\Codex\xtrh\runtime\cluster.local.properties'
```
凭证由安全随机数生成,并限制文件访问;脚本不会输出凭证内容。通过可信方式把这个私有文件复制给同集群的部署电脑。所有电脑使用同一份凭证,节点身份则由各自部署目录自动生成。不要将私有文件提交到仓库或普通共享目录。
### 2. 安装三种角色
总控和网关可以部署在同一台电脑,不同融合电脑安装 `worker`。下面以同机三个实例说明参数:
```powershell
.\scripts\Install-Xtrh.ps1 -Role coordinator -InstallRoot 'E:\Codex\xtrh\runtime\coordinator' -CredentialFile 'E:\Codex\xtrh\runtime\cluster.local.properties'
.\scripts\Install-Xtrh.ps1 -Role gateway -InstallRoot 'E:\Codex\xtrh\runtime\gateway' -CredentialFile 'E:\Codex\xtrh\runtime\cluster.local.properties'
.\scripts\Install-Xtrh.ps1 -Role worker -InstallRoot 'E:\Codex\xtrh\runtime\worker-a' -CredentialFile 'E:\Codex\xtrh\runtime\cluster.local.properties' -Capacity 2 -NodeName '融合电脑A'
```
节点默认配置中没有固定总控 URL。启动后发现总控并注册。复制整个节点的 `data` 目录到另一台电脑会复制节点身份,应每台电脑重新安装并保留各自的 `data/identity.txt`。
每个安装目录包含 JAR、私有集群配置、角色配置、节点身份与 H2 数据、日志和启停脚本。重复安装时需先停止该部署实例,数据和身份不会自动删除。
### 总控是否参与执行
默认安装总控会写入 `fusion.coordinator-worker-enabled=true`,容量使用 `-Capacity` 参数,默认 2 路。要让某台总控只做调度,在安装命令中追加 `-CoordinatorOnly`,生成 `fusion.coordinator-worker-enabled=false`:
```powershell
.\scripts\Install-Xtrh.ps1 -Role coordinator -InstallRoot 'E:\Codex\xtrh\runtime\coordinator' -CredentialFile 'E:\Codex\xtrh\runtime\cluster.local.properties' -CoordinatorOnly
```
只调度模式保留全部控制接口,同时不加载执行服务、媒体控制器和媒体线程池。此开关只影响 coordinator,独立 worker 仍有执行能力,gateway 始终不执行视频任务。已有总控重新安装前应先停止本实例,保留原数据目录和身份,避免新建第二个主节点。
### 3. 启动、停止和自动启动
```powershell
.\scripts\Start-Xtrh.ps1 -InstallRoot 'E:\Codex\xtrh\runtime\coordinator' -JavaHome 'C:\Program Files\Java\jdk-25.0.2'
.\scripts\Start-Xtrh.ps1 -InstallRoot 'E:\Codex\xtrh\runtime\gateway' -JavaHome 'C:\Program Files\Java\jdk-25.0.2'
.\scripts\Start-Xtrh.ps1 -InstallRoot 'E:\Codex\xtrh\runtime\worker-a' -JavaHome 'C:\Program Files\Java\jdk-25.0.2'
.\scripts\Stop-Xtrh.ps1 -InstallRoot 'E:\Codex\xtrh\runtime\worker-a'
.\scripts\Register-XtrhStartup.ps1 -InstallRoot 'E:\Codex\xtrh\runtime\worker-a' -JavaHome 'C:\Program Files\Java\jdk-25.0.2'
```
启动脚本后台隐藏运行,通过本实例的身份和 `/health` 校验启动结果。停止脚本同时核对 PID、启动时间、Java 路径和 JAR 路径,只结束本部署实例。自动启动脚本注册“当前用户登录后启动”的计划任务;使用 `-Remove` 删除该实例的自动启动。无人登录也要运行的部署,需按实际运维账号另行配置 Windows 服务或系统启动任务。
### 4. 网络条件
同网段需要允许 mDNS UDP `5353`,以及总控、网关和节点所用 HTTP 端口;节点播放地址必须能被 PXHJ 观看电脑访问。采集器还需能访问网关 UDP 入口,网关需能访问 PXHJ 的采集入口和路由指定的反向目标。
多网卡时可以在安装参数中指定 `-DiscoveryAddress` 选择发现网卡、`-AdvertisedHost` 固定本机可访问地址。跨网段不保证组播发现,可在统一安装配置中使用 `-CoordinatorUrl 'http://固定总控域名:18100'` 兜底,仍无需在 PXHJ 中逐个添加节点。
## 与 PXHJ 的对接
PXHJ 后端连接总控,使用服务凭证进行内部认证;浏览器不接触服务凭证。PXHJ 试验组织页面展示自动注册的节点、配置路数、任务状态、UDP 路由和演示视频,所有操作仍遵循 PXHJ 的登录权限和试验数据范围。
播放信息的当前同步流程是:节点注册对外服务地址并上报任务就绪结果 → 总控按有效任务版本生成、登记播放地址 → PXHJ 后端约每 1.5 秒通过签名 HTTP 请求读取总控快照,将播放信息和状态保存到 PXHJ 缓存表 → PXHJ 页面查询本项目后端并连接对应节点播放。迁移后任务版本和播放地址随快照更新,PXHJ 会过滤旧代次或旧修订的快照。暂未实现总控主动推送视频地址或上报回调接口。
PXHJ 集成代码已接入现有正式试验页面和后端,并通过隔离 H2 中真实业务服务与实际总控、节点串联的验证。当前达梦主实例已加载新版且实际同步总控状态;RK3588 图片直传及节点迁移已有实测记录,物理多机和真实融合验收尚未完成。
PXHJ 已通过 `optional:file:../config/fusion.local.properties` 加载私有连接配置。可由共享凭证生成这份文件,避免手工复制密钥:
```powershell
.\scripts\Connect-Pxhj.ps1 -PxhjRoot 'E:\pxhj' -CredentialFile 'E:\Codex\xtrh\runtime\cluster.local.properties' -CoordinatorUrl 'http://127.0.0.1:18100' -UdpTargetHost '127.0.0.1'
```
此脚本只写桥接配置,重启 PXHJ 后端后生效。跨电脑部署时,`UdpTargetHost` 填写网关能访问的 PXHJ 后端地址,观看电脑也必须能访问节点的 HTTP 地址。已有配置需确认覆盖范围后使用 `-Force`;私有配置不能提交仓库。
总控控制接口包括:
| 接口 | 用途 |
|---|---|
| `GET /control/info` | 校验总控身份、集群与调度代次 |
| `GET /control/snapshot` | PXHJ 汇总查询节点、任务、网关、路由 |
| `POST /control/nodes/register` | 节点自动注册 |
| `POST /control/nodes/{id}/heartbeat` | 节点报告准备结果并领取当前任务 |
| `PATCH /control/nodes/{id}/capacity` | PXHJ 修改容量和启用状态 |
| `POST /control/contexts/sync` | PXHJ 下发已保存的试验及真实轮次上下文 |
| `POST /control/image-sources/register` | PXHJ 经设备认证后请求短期原图上传许可 |
| `POST /control/image-sources/resolve` | PXHJ 查询原图任务当前有效接收节点 |
| `PUT /control/routes` | 下发登记的采集来源及转发目标 |
| `POST /control/gateways/heartbeat` | 网关报告统计并领取最新路由 |
媒体入口为 `/media/{taskId}/{version}/stream`,任务版本和临时媒体许可用于阻止旧任务播放;按任务类型输出演示帧或接收到的原图,真实融合输出后续接入。原图私有元数据和 JPEG 接口为 `/node/images/{taskId}/{version}/latest`、`/node/images/{taskId}/{version}/frames/{frameId}`,由 PXHJ 后端签名访问。
软件安装不会自动开启现场设备协商。启用每个采集器前需核对原图片回退地址、网关端口及 PXHJ 来源登记;本次已按用户授权完成当前 RK3588 的配置和联调。