Commit Graph

14 Commits

Author SHA1 Message Date
KodouWZF
339f2c34ab chore(git): 镜像 tar 与 demo/ 历史拷贝不进气仓,.gitattributes 锁 LF 行尾 2026-11-04 21:44:54 +08:00
KodouWZF
fa77c561c0 docs(传输): 补基线 jar 对照实验,作废旧的 45.9 秒基线与 52×/31× 口径
用 4eb67e2 单独构建基线镜像跑 A/B 两组:A 组把监听周期摁成 5 秒隔离 I/O 改动,
B 组用基线自带 60 秒周期量真实改前端到端。

实测:组包 10,055/10,622 ms → 881 ms(11.4×),解包 7,777 → 785 ms(9.9×),
端到端 123.1 s → 9.9 s。原 45,934 ms 基线不可复现,§2.1/§3.4/§10.3/§10.5
中据此推算的数字全部改正。B 组 123 秒正好复现客户「两分钟传不到内网」的说法,
且其中 102 秒是轮询等待——瓶颈主要是 5.1 而非组包。
2026-11-03 23:47:46 +08:00
KodouWZF
2c93c545b1 docs(传输): 补真实端到端实测数据,并记录包完整性校验空转缺陷
组包 45.9s → 881ms,外网解包入库 785ms,端到端 9.9s(其中 8s 是两次轮询等待)。
实测同时暴露:transferMetadata.json 里 fileSize 全为 null,接收侧的
大小校验因 0 != 0 判据恒真而直接放行,截断包会被当成完整包解包并静默丢文件。
2026-11-03 23:22:22 +08:00
KodouWZF
7758b4961b docs(传输): 补 5.2 实施情况与实测记录
三个坏包/坏标记样本的实测结果、每轮结构化日志原文、单轮耗时 17-41ms。
明确记录认领改名与并发解包未实施及理由(单实例 + Spring cron 不重叠,
已实测触发间隔精确 5.00 秒),以及改用 mtime 静止阈值区分「还在搬」与「坏包」。

同步修正 5.2 的实施状态、第 8 节配置项(去掉 concurrency、
max-unpack-size-mb 默认值由建议 1024 改为已实施 512、新增 stale-after-seconds)、
第 9 节实施顺序表的收益口径(31 倍理论值改为实测 8.2 倍/17.6 倍)。
2026-11-03 22:43:59 +08:00
KodouWZF
06852c5d90 perf(传输): 单轮处理上限从「10 个」改为「4 秒时间预算」
个数不代表工作量:几十 KB 与几百 MB 的包差三个数量级,10 个小包 1 秒就跑完
(限制毫无必要),10 个大包能跑十几分钟(还会把下一轮挤掉)。改为时间预算后
单轮能处理多少就处理多少,超预算结束本轮、剩余留给下一轮,个数上限 500 兜底。
按 5.3 改造后的单包耗时估算,4 秒预算约可处理数十个小包,吞吐提升一个数量级。

同时解决三个会让预算被白耗的问题:
- 校验不通过原来只有一种处理(静默跳过、永不改名),但它有两重含义:光闸还在搬
  (下一轮就好)与包本身坏了(永远不会好)。用 mtime 是否静止超过 stale-after-seconds
  区分,坏包改名 .error 停止重试,否则 5 秒轮询会为它无限白跑
- 解包异常同样按静止阈值判定,短暂基础设施抖动仍保留重试
- .finish 文件名不合规原来只 log.warn 后保留文件,每轮重复解析并刷日志,改为标 .error

.finish 只做一次状态更新,改为优先处理且不受个数限制,让发送端尽早看到「已完成」。
每轮结束输出结构化日志(完成标记/成功/坏包/未就绪/耗时/预算/剩余/已搁置),
剩余超过 50 告警,作为容量规划依据。

按方案 5.3 注意事项补 max-unpack-size-mb(默认 512):解包把整个 entry 读进堆,
upload 再拷一份、MD5 再一份,峰值约 2-3 倍文件大小,-Xmx3g 下单文件过大会 OOM,
超限直接标 .error 而不是尝试解包。

verifyFileMD5 打不开 zip 时原来记 ERROR 带堆栈,但「光闸还在搬」本来就是这个状态,
5 秒轮询下会为每个在途文件刷 60 条 ERROR,降为 debug;真正的坏包由改名 .error 时记 ERROR。

未实施方案里的认领改名与并发解包:两侧都是单实例部署,Spring 的 cron 任务要等上一轮
跑完才排下一轮(已实测触发间隔精确 5.00 秒),不存在同实例重叠;认领机制只会引入
kill -9 后遗留 .processing 这类新故障模式,换不到吞吐。若将来改多实例共享同一摆渡目录,
再补认领与 Redisson 互斥。
2026-11-03 22:42:06 +08:00
KodouWZF
75ab51e13c docs(传输): 补一期实施与本地实测记录
监听周期实测精确 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 往返、现场系数)。
2026-11-03 22:22:27 +08:00
KodouWZF
456b1ea62d perf(传输): 已压缩格式组包时不再二次压缩
pptx/docx/xlsx/zip/mp4/jpg 这类本身已压缩的格式,再跑一遍 level 6 deflate
压缩率接近 0,但 CPU 照样全量消耗(约 0.04 秒/MB)。改为按文件名后缀判断,
命中清单的 entry 用 Deflater.NO_COMPRESSION,其余保持默认 level 6。

不用 ZipEntry.STORED 是因为它要求预先提供 size 和 CRC-32,会多一遍顺序读;
level 0 产出的仍是合法 zip(DEFLATE 存储块),接收端解包与校验逻辑无需改动。
清单从严,只收确定已压缩的格式,避免可压缩文件被误判导致包体变大。
元数据 JSON 可压缩,写它之前显式还原 level。
2026-11-03 22:07:00 +08:00
KodouWZF
c5d19f47a2 perf(传输): xs_file_record.md5_code 补索引
文件入库时用 MD5 做内容去重查询(FileServiceImpl 上传后 find(md5Code)),
该列此前没有索引,每个文件入库都是一次全表扫描。解包一个含 N 个文件的
传输包就是 N 次全表扫描,300 人规模下 xs_file_record 达数万行时,
单文件入库可省几十到几百毫秒,100 个文件的包可省数秒到数十秒。

按 init 与 upgrade 双写:MySQL 版 DDL 加 KEY,PG 版加 CREATE INDEX,
新建 upgrade-20261103-transfer-perf.sql 供已上线环境增量执行
(DM8 走第 1 节,PG 走第 2 节,并给出 CONCURRENTLY 备选)。
交付包 sql/01-init-table.sql 按 README 要求从仓库整份覆盖,不手改副本。
2026-11-03 22:03:33 +08:00
KodouWZF
06fb35b984 perf(传输): 摆渡目录监听周期 1 分钟改为 5 秒
端到端延迟里有一半是轮询空等:收发两侧各等一次,1 分钟周期下平均空等
60 秒、最坏 120 秒,这是「一页文件也要 2 分钟」的主因,而真正干活不到 2 秒。

改成 5 秒是安全的:空目录一轮只有两次 Files.list + 过滤,开销可忽略;
Spring 的 cron 任务要等上一轮跑完才排下一轮,同一实例内不会重叠。
副作用是损坏包被更频繁重试(失败包当前不删除也不改名,mtime 最老所以
每轮排第一),彻底解决靠方案 5.2 的 .error 改名让位。

部署说明第 10 条原来写「不要改成秒级」,与新默认值矛盾,一并纠正。
2026-11-03 22:01:25 +08:00
KodouWZF
4114c1f434 perf(传输): 组包与解包缓冲区 512B/8KB 提升到 64KB
JDK8 的 ZipOutputStream 内部 deflate 输出缓冲硬编码 512 字节且不可配置,
必须在外层包 BufferedOutputStream 才能减少落盘次数;读侧 8KB 同样偏小。
传输目录与文件存储目录都是宿主机 bind mount,单次 syscall 可能跨
FUSE/网络/光闸监控驱动边界,实测成本约 1ms,小缓冲把耗时放大数十倍。

改 5 处:组包输出流、组包读源文件、解包输入流、解包读 entry、
本地存储落盘。每 MB 的 syscall 次数从 2176 降到 32,
按实测模型 50MB 组包从约 117s 降到约 3.8s。

方案见 backend/docs/传输链路性能优化方案.md 第 5.3 节。
2026-11-03 21:57:28 +08:00
KodouWZF
f817bf0701 docs(传输): 跨网传输链路性能优化方案与现场验证方法
现场反馈一页文件要 2 分钟才进内网。实测组包 19.6MB 耗时 45.9s,
其中 SQL 仅 57ms,其余全在文件 I/O,折算 2.33 秒/MB,比正常 deflate
慢 50-100 倍,根因是 512B/8KB 小缓冲在 bind mount 上放大 syscall 次数。

沉淀耗时归因模型、不改代码即可切分端到端 6 段的现场测量方法、
6 项优化的改法与验收标准,以及本次明确不做的事及理由。
2026-11-03 21:57:15 +08:00
KodouWZF
4eb67e246e feat(交付): 客户侧两台服务器离线部署包
内网机/外网机各起一套栈,两台之间不开任何端口,文件只经光闸在
gate/out 与对端 gate/in 之间单向摆渡。一份 compose + 一份 config +
一份 nginx 模板,全部差异收在 .env 里。

- docker-compose.yml:5 服务只发布前端端口;app 容器 IP 锁死并由
  compose 注入 -Dcode.snowflake.workid.<IP>=<WORK_ID>,绕开兜底 99
  超雪花 5 位上限导致启动即崩的问题
- .env.iw / .env.ow:出厂配置与随机口令已填好,仅 MESHSAFE_SECRET
  故意留占位(以 MeshSafe 侧白名单为准);按 maintainer 决定原样入库
- install.sh iw|ow:按角色建 .env -> 自检 -> sha256 校验 tar -> 架构
  核对 -> docker load 后校验 tag -> 建目录/属主/SELinux 标签 -> 起栈
  并逐个等健康。修掉 pipefail 下 `grep | head -1` 静默中断、架构字段
  误读 manifest.json(实际在 Config blob)、die() 未定义先被调用
- export-images.sh:就地刷新 images/*.tar、sql、.env 的 tag 与
  SHA256SUMS,再打 dist 交付盘;tar 与 SHA256SUMS 由 .gitignore 排除
- sql/01+02:从 backend/db 的 PG 全量与初始数据覆盖拷贝。三个
  upgrade-*.sql 的 PG 段(x_upload_config、x_file_security)已在
  init-table-postgres-full.sql 内,空库跑 01->02 即完整现状
- smoke_test.py:18 条断言的现场验收,凭证全部走环境变量
- 部署说明.md:拓扑、交付清单、出厂口令表、iw/ow 差异、验收清单、
  13 条已知坑

镜像 tar 不进 git,装机包由 export-images.sh 出盘。
v1.0.0
2026-11-02 20:40:16 +08:00
KodouWZF
3910239b87 fix(前端): 弹窗内容被长文件名撑破右边框
DialogContent 的 grid 用隐式 auto 轨道,轨道 min 受 grid item 的
min-width:auto 支配。传输/分享确认框里「被拦截文件清单」是不换行文本,
把 400px 弹窗(扣 p-6 后仅 350px 可用)的轨道顶到 386.8px,
内容整体从右边框外溢 11px。

- dialog.tsx 加 grid-cols-1,轨道只跟容器宽,24 个弹窗共用此修复
- SecuritySkipWarning 的文件名由 truncate 改 break-all:原截断把要警告
  的文件名省略号掉了,用户看不清哪几个文件被拦

实测(重建 sfile-web 镜像后):轨道 350px、告警块右边缘 939 <= 弹窗 963、
清单横向溢出 0、4 条文件名完整可读;移动/分享/传输三个弹窗回归无溢出,
全屏预览弹窗的 flex 经 tailwind-merge 覆盖基类 grid,不受影响。
2026-11-02 20:39:45 +08:00
KodouWZF
47273ae3fd init: 信创文件安全传输系统内外网本地 Docker 部署
包含 s-file 后端、React 前端、MeshSafe 安全检测对接,以及内外网两套
compose/nginx/配置(仅前端 28180/28280 对外发布,其余端口不暴露)。

说明:deploy/config/application-iw.yml 与 application-ow.yml 按维护者
明确要求原样入库,其中含本机 Docker 用的库口令、RabbitMQ 口令与 JWT
密钥;上生产前需替换。
2026-11-02 10:59:03 +08:00