返回开发日志

2026-06-24

Anura 上线部署与采集链路修复报告

Anura 在移动端测试通过后完成采集链路重构、线上部署、加载优化和开始测量链路修复。

---

date: 2026-06-24

author: Izzy

---

Anura 上线部署与采集链路修复报告

本报告只记录 6 月 23 日移动端调试报告之后的增量工作。

上次报告已经覆盖了手机端摄像头、人脸框跟随、准备阶段、前置摄像头、移动端诊断方式等内容;这里不重复展开。

本次更新概览

本次工作重点从“移动端准备阶段可用”推进到“线上环境可访问,并且点击开始后能进入正式测量链路”。

  • 先重构采集链路:把准备、预览、正式采集、chunk 上传、结果轮询拆开。
  • 再完成线上部署:Anura 上线到 https://anura.sdgs-hegp.org.cn/
  • 随后做性能优化:大模型、WASM、JS、CSS 改为更合理的缓存和静态服务方式。
  • 最后修复开始测量问题:处理 DFX 输入结构、时间戳、按钮防重入和失败日志。

这次工作的核心变化,是从“准备阶段能跑”推进到“正式测量链路能在线上跑”。

采集链路重构

移动端准备阶段通过后,正式测量链路仍然存在状态错位:用户看到“已准备”,但点击开始后不一定真正进入采集。

这部分重构主要处理四件事:

1. 准备阶段和正式采集阶段分离

  • 准备阶段只负责摄像头、人脸检测、画面质量判断。
  • 正式采集阶段才启动 DFX collector、创建 measurement、生成 chunk、上传 chunk。

2. 采集进度按用户感知重整

  • 进度展示从偏技术的 chunk 逻辑,调整为更贴近用户理解的秒级进度。
  • 读秒结束后明确进入后运算,而不是让用户误以为页面卡住。

3. DFX collector 生命周期梳理

  • 开始采集前重新确认 collector 状态。
  • 避免复用错误状态下的 collector。
  • chunk 生成和上传顺序增加校验,减少前端 measurement 和后端记录错位。

4. 结果链路重新对齐

  • 采集结束后进入结果轮询。
  • 保留 chunk 与结果顺序的对应关系。
  • 让“采集完成”和“结果展示”之间的状态更清楚。

上线部署

采集链路重构后,Anura 被部署到线上环境:

https://anura.sdgs-hegp.org.cn/

本次上线包含以下工作:

模块处理内容当前状态
:--:--:--
HTTPS配置线上证书已完成
Nginx接管公网入口和静态资源服务已完成
后端服务使用 systemd 管理 Node API 服务已完成
API 健康检查验证 /api/health已通过
DeepAffex 代理服务端承接 session、measurement、chunk、results已接入

这一步的意义是:Anura 从本地调试状态进入可线上访问状态,后续测试不再依赖开发机和局域网。

加载速度优化

上线后暴露出新的体验问题:loading face modelDFX 初始化较慢。

处理方式如下:

  • Nginx 直接服务前端静态资源
  • 大文件不再通过 Node/Fastify 转发。
  • WASM、模型文件、JS、CSS 由 Nginx 直接返回。
  • 大资源增加长期缓存
  • WASM、模型、JS、CSS 设置 30 天缓存。
  • 对复访用户和同设备二次测试更友好。
  • dfx.js 去掉 no-store
  • 之前每次都会重新请求。
  • 现在允许浏览器缓存。
  • DeepAffex study config 增加服务端缓存
  • 同一 study config 服务端缓存 10 分钟。
  • 短时间内多用户访问时,准备阶段响应更快。
用户类型体验变化
:--:--
新用户首次打开仍需下载大模型,但服务更稳,传输路径更短
同一用户再次打开浏览器缓存命中,加载明显更快
短时间内多用户访问服务端 study config 可复用,准备阶段更快

开始测量问题修复

上线后继续测试时,出现了“点击开始测量后又回到准备状态”的问题。

这个问题不是一个单点 bug,而是正式采集开始处连续暴露了多层问题。

1. 开始按钮重复触发

现象:

  • 用户点击开始后,短时间内可能创建多个 measurement。
  • 页面看起来回到准备状态,用户会误以为没有真正开始。

处理:

  • 增加开始按钮的 in-flight 防重入锁
  • 点击开始前重置取消状态。
  • 异常恢复后再允许重新开始。

2. DFX 人脸关键点结构不一致

现象:

  • 准备阶段能看到人脸。
  • 正式采集第一帧进入 DFX 后失败。

定位:

  • demo 使用扁平结构:
  • x
  • y
  • z
  • valid
  • estimated
  • quality
  • 本地版本此前使用嵌套结构:
  • point: { x, y, z }

处理:

  • DFX 输入结构改为与 demo 一致。
  • 修复“准备可用,但正式采集第一帧失败”的断点。

3. MediaPipe 和 DFX 时间戳冲突

现象:

  • 点击开始后立即失败。
  • 日志中出现 MediaPipe 时间戳倒退错误。

原因:

  • MediaPipe 需要持续递增的全局时间。
  • DFX 更适合使用本次测量开始后的相对时间。
  • 之前把相对时间同时传给 MediaPipe,导致 MediaPipe 认为时间倒退。

处理:

  • MediaPipe 使用全局递增时间。
  • DFX 使用测量开始后的相对时间。

这一步修复后,预览阶段和正式采集阶段可以平滑切换。

诊断能力补强

这次也补强了线上问题定位能力。

  • 前端失败日志会上报到服务端。
  • 长错误信息会截断后再上报,避免因为超过长度限制导致整条日志丢失。
  • 服务端日志现在可以看到:
  • 当前页面状态
  • 是否点击开始
  • measurement 是否创建
  • DFX collector 是否启动
  • 是否进入 chunk 上传
  • 失败原因

这次诊断补强的价值是:后续问题可以从日志判断断在哪一段,而不是只依赖用户描述。

本次结果

项目本次处理结果
:--:--
移动端准备后正式采集已修复开始后立即回到准备状态的问题
线上访问已完成 Anura 线上部署
加载速度已完成静态资源和 SDK 配置缓存优化
DFX 输入已对齐 demo 的人脸关键点结构
时间戳已拆分 MediaPipe 与 DFX 的时间逻辑
线上排查已补充失败日志上报

结论

本次工作不是继续处理“能不能看到人脸框”,而是解决上次报告之后暴露出的下一层问题:

用户点击开始后,是否真的进入线上正式测量链路。

目前这一段已经完成上线部署、采集链路重构、加载优化和开始测量修复。下一次测试重点应放在完整 30 秒采集后的结果稳定性和展示体验上。