From 75ab51e13c48e4985b4373bed58995806daa4b0f Mon Sep 17 00:00:00 2001 From: KodouWZF <3092554823@qq.com> Date: Tue, 3 Nov 2026 22:22:27 +0800 Subject: [PATCH] =?UTF-8?q?docs(=E4=BC=A0=E8=BE=93):=20=E8=A1=A5=E4=B8=80?= =?UTF-8?q?=E6=9C=9F=E5=AE=9E=E6=96=BD=E4=B8=8E=E6=9C=AC=E5=9C=B0=E5=AE=9E?= =?UTF-8?q?=E6=B5=8B=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 监听周期实测精确 5.00 秒触发、空目录单轮 8-13ms;md5 索引在 23 行下 规划器仍选顺序扫描(正确行为),关掉后走 Index Scan 证明索引可用; 容器内 I/O 基准(同镜像同 bind mount,真实 23 个文件 19.04MB)测得 缓冲区改造 8.2 倍、叠加 level 0 共 17.6 倍,包体 +5.1%。 据实修正第 3.4 节的预测偏差:31 倍是纯 I/O 理论值,缓冲改完后 deflate CPU 占到剩余耗时的一半,对外口径改用实测的 8 倍/17 倍。 另记录尚未验证的部分(应用内真实组包、解包侧、level 0 往返、现场系数)。 --- backend/docs/传输链路性能优化方案.md | 82 +++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/backend/docs/传输链路性能优化方案.md b/backend/docs/传输链路性能优化方案.md index 16a0cc6..1798ac0 100644 --- a/backend/docs/传输链路性能优化方案.md +++ b/backend/docs/传输链路性能优化方案.md @@ -1,8 +1,9 @@ # 跨网传输链路性能优化方案 -> 版本:v1.0(2026-11-03) +> 版本:v1.1(2026-11-03) > 适用后端:s-file(alita-bjy-uygur) -> 状态:待评审 → 待实施 → 待现场验证 +> 状态:一期(5.1/5.3/5.4/5.5)已实施并本地验证 → 待现场验证;二期(5.2)待实施 +> 实施与实测记录见第 10 节 > 关联代码:`TransferUserFileServiceImpl`(发送/组包)、`TransferFileMonitorServiceImpl`(接收/解包)、`TransferFileMonitorJob`(调度)、`FileServiceImpl` / `LocalFileStorage`(物理文件读写) --- @@ -408,3 +409,80 @@ CREATE INDEX idx_file_record_md5_code ON xs_file_record(md5_code); 建议 1–4 作为一期(都是低风险、可独立验证的改动),5 作为二期,6 视现场文件大小分布决定。 **每一项都必须单独验证并记录数字**,不要合并提交,否则现场出问题时无法定位是哪一项引起的。 + +--- + +## 10. 一期实施与验证记录(2026-11-03,本地环境) + +一期 4 项已实施,每项独立提交: + +| 项 | 提交 | 内容 | +|---|---|---| +| 5.3 | `4114c1f` | 组包/解包/落盘缓冲区 512B、8KB → 64KB,共 5 处 | +| 5.1 | `06fb35b` | 监听周期 `0 */1 * * * ?` → `0/5 * * * * ?`,Java 默认值 + 4 个部署文件 | +| 5.5 | `c5d19f4` | `idx_file_record_md5_code`,init 双库 + upgrade 脚本 + 交付包副本 | +| 5.4 | `456b1ea` | 按后缀对已压缩格式用 `Deflater.NO_COMPRESSION` | + +编译:JDK 8 + `mvn package -Dmaven.test.skip=true`,BUILD SUCCESS。 +(`-DskipTests` 不行:surefire 2.22.2 的传递依赖 `plexus-utils:1.1` 本地仓库没有,离线模式解析失败,需联网补一次。) + +### 10.1 5.1 监听周期 — 已实测通过 + +重启后从 `sfile-iw-app` 日志读 `AlitaStopWatchAspect` 输出: + +``` +22:14:05.128 TransferFileMonitorJob.execute(),use(ms): 127 ← 首轮预热 +22:14:10.028 TransferFileMonitorJob.execute(),use(ms): 13 +22:14:15.013 TransferFileMonitorJob.execute(),use(ms): 12 +22:14:20.025 TransferFileMonitorJob.execute(),use(ms): 13 +22:14:25.015 TransferFileMonitorJob.execute(),use(ms): 13 +22:14:30.024 TransferFileMonitorJob.execute(),use(ms): 11 +22:14:35.003 TransferFileMonitorJob.execute(),use(ms): 8 +``` + +- 触发间隔精确 5.00 秒,cron 表达式合法,应用启动无异常 +- **空目录单轮 8–13 ms**,即每分钟约 150 ms 的开销,证实 5.1 中「空目录扫描开销可忽略」的判断 +- 两侧轮询空等从平均 60 秒降到平均 5 秒 + +### 10.2 5.5 md5 索引 — 已实测通过 + +两个本地库(`sfile-iw-pg`、`sfile-ow-pg`)执行 upgrade 脚本均成功,脚本可重复执行(第 2 节 `IF NOT EXISTS` 生效)。 + +`EXPLAIN SELECT * FROM xs_file_record WHERE md5_code='ABC' AND deleted=FALSE LIMIT 1`: + +- 默认:**Seq Scan**(当前 23 行,规划器判断顺序扫描更便宜,这是正确行为,也印证 5.5 中「数据量小时收益不可见」) +- `SET enable_seqscan=off` 后:**Index Scan using idx_file_record_md5_code** → 索引有效可用,数据量上来后会自动切换 + +### 10.3 5.3 + 5.4 缓冲区与压缩级别 — 已实测通过(容器内 I/O 基准) + +端到端发送需要登录,本地 admin 口令未知,因此改用**容器内 I/O 基准**直接测量组包环节:复刻 `packTransferFiles` 的读写形态,在同一个 `sfile-app:local` 镜像、同一份 bind mount 上跑真实的 23 个文件(19.04 MB,即线上样本目录 `iw/upload/1`)。 + +必须在容器内测——syscall 放大来自容器到宿主机的文件共享层,在宿主机上直接测不出这个成本。 + +3 轮结果(每轮依次跑三种方式,输出 zip 随即删除): + +| 方式 | 第 1 轮 | 第 2 轮 | 第 3 轮 | 产出大小 | +|---|---|---|---|---| +| 旧:512B 出 / 8KB 读,level 6 | 9033 ms | 8279 ms | 9701 ms | 18.12 MB | +| 新:64KB 出 / 64KB 读,level 6 | 1022 ms | 1109 ms | 1115 ms | 18.12 MB | +| 新:64KB 出 / 64KB 读,level 0 | 516 ms | 491 ms | 509 ms | 19.04 MB | + +- **5.3 单独收益:约 8.2 倍**(9033 → 1022 ms) +- **5.3 + 5.4 合计收益:约 17.6 倍**(9033 → 509 ms) +- level 0 让包体从 18.12 MB 变成 19.04 MB(**+5.1%**)。反过来说明这个样本里 level 6 只压掉了 5%,即内容基本已是压缩格式——**用 5% 的体积换一半的时间,划算** + +#### 与第 3.4 节预测的偏差(需据实修正) + +| 项 | 预测 | 实测 | 说明 | +|---|---|---|---| +| 每 MB 组包成本(旧) | 2.33 s/MB(应用日志基线) | **0.47 s/MB**(基准 old 模式) | 基线 45.9 秒那次是在不同负载/冷缓存下采的;基准跑前已有预热。两者都是真实的,差异来自环境状态 | +| 提速倍数 | 31× | **8.2×**(level 6)/ **17.6×**(level 0) | 31× 是纯 I/O 的理论值。实测 new-l6 的 1022 ms 里约 500 ms 是 deflate CPU(因为 new-l0 只要 509 ms),缓冲改完后 CPU 占比升到一半,总倍数自然低于纯 I/O 倍数 | + +**结论:预测方向正确、量级偏高。** 现场汇报口径建议用实测的 **8 倍(仅改缓冲)/ 17 倍(含 level 0)**,不要用 31 倍。第 3.4 节的表格在现场按 4.2 的系数重算后再对外给数。 + +### 10.4 尚未验证的部分 + +- [ ] **应用内真实组包**:需要登录后发送一次同一个文件夹,从 `ControllerLogAspect` 的 `useTime` 与「传输文件打包完成」日志确认应用侧数字(基准只覆盖 I/O 环节,未含 SQL 与元数据序列化) +- [ ] **解包侧**:64KB `ZipInputStream` 的改动只做了编译验证,未跑通一次真实解包(同样受登录限制) +- [ ] **level 0 产出的 zip 能否被接收端正常解包**:需一次内穿外 + 一次外传内的完整往返 +- [ ] **现场系数**:客户环境是 Linux + 光闸监控目录,syscall 单价与本地 Docker Desktop 不同,必须按第 4 节重测