Files
dp/docs/production-architecture.md
T
2026-07-17 02:10:08 +08:00

6.4 KiB
Raw Blame History

生产架构说明

目标

本项目用于把一个逻辑尺寸为 14880 x 3510 的 LED 大屏内容,拆分到两台 GPU 输出服务器本地渲染。

生产形态:

  • 控制服务运行 FastAPI,负责场景、动作、时间同步、ACK、状态监控。
  • 左 GPU 服务器打开 /output/left,只显示左半屏 tile。
  • 右 GPU 服务器打开 /output/right,只显示右半屏 tile。
  • 每台 GPU 服务器输出 4 路 4K 到拼控或 LED 控制器。
  • 拼控或 LED 控制器完成最终物理拼接。

WebSocket 不传大视频流,只传状态、命令、时间、ACK 和性能指标。画面由两台 GPU 服务器本地渲染。

逻辑拓扑

                      控制台 /
                 http://control:8000/
                           |
                           v
                   FastAPI 控制服务
       场景管理 / WebSocket Hub / SyncCoordinator / 状态接口
                  |                      |
       prepare/commit/action      status/telemetry/ACK
                  |                      |
        -------------------------------
        |                             |
        v                             v
 左 GPU 输出服务器                 右 GPU 输出服务器
 /output/left                     /output/right
 left tile 本地渲染               right tile 本地渲染
 4 路 4K 输出                     4 路 4K 输出
        |                             |
        ---------> 拼控 / LED 控制器 <-
                       14880 x 3510

Tile 切分

完整逻辑画面:

|-------------------------- 14880 --------------------------|
|------------ left 7440 ------------|-------- right 7440 ----|

config/tiles.json 定义:

left:
  x=0
  y=0
  width=7440
  height=3510

right:
  x=7440
  y=0
  width=7440
  height=3510

输出端页面使用完整逻辑大屏坐标系,再根据自己的 tile 做视口偏移。Three.js 项目中建议使用:

camera.setViewOffset(
  fullWidth,
  fullHeight,
  tile.x,
  tile.y,
  tile.width,
  tile.height,
);

每台服务器 4 路 4K

每台 GPU 服务器建议配置为 2 x 2 逻辑桌面:

7680 x 4320

四路输出映射:

1: x=0,    y=0,    3840 x 2160
2: x=3840, y=0,    3840 x 2160
3: x=0,    y=2160, 3840 x 2160
4: x=3840, y=2160, 3840 x 2160

单侧业务 tile 是 7440 x 3510,可以放入该逻辑桌面。

同步协议

场景切换

控制台调用:

POST /api/scenes/{scene_id}/switch

服务端生成同一个 command_id,先广播:

prepare_scene(command_id, apply_at_ms, state, scene)

输出端收到 prepare_scene 后:

  1. 预加载资源。
  2. 等待至少两个 RAF,让浏览器完成布局和首帧准备。
  3. 如果存在 window.ledPlatformPrepareScene,等待业务方的真实预渲染/超分完成。
  4. 回 ACKstatus=prepared

服务端 SyncCoordinatortarget_tiles 中的 leftright 都返回 prepared 后,才广播:

commit_scene(command_id, apply_at_ms, state, scene)

输出端收到 commit_scene 后,等到统一的 apply_at_ms 再切换画面,并回 ACK

status=committed

这样谁渲染慢就等谁,两个输出端都准备好后才同步放行。

局部动作

控制台调用:

POST /api/actions

支持动作:

page.next
page.prev
energy.mode
security.alert
timeline.pause
timeline.resume

局部动作目前直接按 apply_at_ms 调度并回 ACK

status=action_committed

如果后续某些局部动作也需要超分或重资源准备,可以复用场景切换的 prepare/barrier/commit 模式。

画面回显

控制台内置两个只读预览 iframe,并把它们无缝拼成一块完整画面:

/output/left?preview=1
/output/right?preview=1

预览模式通过 /ws/admin 接收状态和命令,不连接 /ws/output/{tile_id},因此:

  • 不注册为真实输出节点。
  • 不发送 preparedcommittedtelemetry ACK。
  • 不会提前释放同步 barrier。
  • 只用于控制台观察画面。

真实生产输出端仍然打开:

/output/left
/output/right

时间同步

输出端通过 clock_ping / clock_pong 估算服务端时间:

serverNowMs = Date.now() + serverOffsetFromDateMs

RTT 使用 performance.now() 估算,服务端时间偏移使用客户端 wall clock 的发送时间和返回时间中点估算。

渲染和动画应基于统一时间轴:

const t = serverNowMs() - sceneStartedAtMs;
renderSceneAt(t);

不要让左右输出端各自累计本地 delta:

// 不推荐
animation += localDeltaTime;

状态观测

控制台显示:

  • 输出节点数量。
  • 每个输出节点 FPS、frame time、RTT、clock offset。
  • 最近命令回显。
  • 每个 tile 的 preparedcommittedlateerror 状态。
  • barrier 放行耗时。

接口:

GET /api/sync/status
GET /healthz

为什么不传视频流

单侧半屏未压缩数据量约为:

7440 x 3510 x 4 bytes x 60 fps ~= 6.3 GB/s

左右两侧合计超过 12 GB/s。普通网络视频流还需要编码、传输、解码,会带来延迟、画质损失、文字细线压缩失真,以及新的编码/解码同步问题。

本系统选择“控制服务发命令,输出端本地渲染”,更适合高分辨率 LED 墙。

生产验收指标

建议关注 P95/P99

60 FPS:
  P95 frame time < 16.67ms
  P99 frame time < 20ms

30 FPS:
  P95 frame time < 33.33ms
  P99 frame time < 40ms

同步指标:

WebSocket RTT < 10ms
clock offset < 5ms
left/right 都返回 prepared
left/right 都返回 committed 或 action_committed
不得频繁出现 late ACK

硬件建议:

  • 两台输出服务器尽量使用同型号 GPU、同驱动、同浏览器版本。
  • 电源策略设置为高性能。
  • 关闭系统休眠、屏保、自动更新弹窗。
  • 拼控侧开启输入缓存、帧同步或延迟对齐能力。
  • 生产环境使用 PTP 或内网 NTP。

边界

能保证:

  • 两边业务状态一致。
  • 两边都准备好后才释放场景提交。
  • 两边按统一服务端时间点提交。
  • 动画长期不漂移。
  • 命令和性能可观测。

不能单独保证:

  • 两张不同 GPU 的物理扫描完全同相。

如果必须达到广播级帧同步,需要硬件层支持 Genlock / Frame Lock / 专业视频墙控制器。