From 06fb35b984c287085f39e2ac57e69878c9bce37a Mon Sep 17 00:00:00 2001 From: KodouWZF <3092554823@qq.com> Date: Tue, 3 Nov 2026 22:01:25 +0800 Subject: [PATCH] =?UTF-8?q?perf(=E4=BC=A0=E8=BE=93):=20=E6=91=86=E6=B8=A1?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E7=9B=91=E5=90=AC=E5=91=A8=E6=9C=9F=201=20?= =?UTF-8?q?=E5=88=86=E9=92=9F=E6=94=B9=E4=B8=BA=205=20=E7=A7=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 端到端延迟里有一半是轮询空等:收发两侧各等一次,1 分钟周期下平均空等 60 秒、最坏 120 秒,这是「一页文件也要 2 分钟」的主因,而真正干活不到 2 秒。 改成 5 秒是安全的:空目录一轮只有两次 Files.list + 过滤,开销可忽略; Spring 的 cron 任务要等上一轮跑完才排下一轮,同一实例内不会重叠。 副作用是损坏包被更频繁重试(失败包当前不删除也不改名,mtime 最老所以 每轮排第一),彻底解决靠方案 5.2 的 .error 改名让位。 部署说明第 10 条原来写「不要改成秒级」,与新默认值矛盾,一并纠正。 --- .../java/com/senmesh/sfile/job/TransferFileMonitorJob.java | 5 +++-- deploy/offline/.env.example | 5 +++-- deploy/offline/.env.iw | 2 +- deploy/offline/.env.ow | 2 +- deploy/offline/docker-compose.yml | 2 +- deploy/offline/部署说明.md | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/com/senmesh/sfile/job/TransferFileMonitorJob.java b/backend/src/main/java/com/senmesh/sfile/job/TransferFileMonitorJob.java index eca4d04..acef1bf 100644 --- a/backend/src/main/java/com/senmesh/sfile/job/TransferFileMonitorJob.java +++ b/backend/src/main/java/com/senmesh/sfile/job/TransferFileMonitorJob.java @@ -24,9 +24,10 @@ public class TransferFileMonitorJob { /** * 定时扫描传输目录 - * 默认每分钟执行一次 + * 默认每 5 秒执行一次。cron 任务由 Spring 在上一次执行完成后才排下一次, + * 同一实例内不会重叠;多实例共享同一摆渡目录时需另加认领/互斥机制。 */ - @Scheduled(cron = "${file.transfer.monitor.cron:0 */1 * * * ?}") + @Scheduled(cron = "${file.transfer.monitor.cron:0/5 * * * * ?}") @AlitaStopWatch public void execute() { try { diff --git a/deploy/offline/.env.example b/deploy/offline/.env.example index f62c925..276914f 100644 --- a/deploy/offline/.env.example +++ b/deploy/offline/.env.example @@ -85,5 +85,6 @@ TZ=Asia/Shanghai # 按机器内存调整,堆外还需预留 1G 左右 APP_JAVA_OPTS=-Xms1g -Xmx3g -Dfile.encoding=UTF-8 REDIS_MAXMEMORY=512mb -# 跨网文件监听任务周期,默认每分钟扫一次摆渡目录 -FILE_TRANSFER_MONITOR_CRON=0 */1 * * * ? +# 跨网文件监听任务周期,默认每 5 秒扫一次摆渡目录。 +# 调慢可减少空目录扫描,但端到端延迟会按周期的一半叠加(收发两侧各一次) +FILE_TRANSFER_MONITOR_CRON=0/5 * * * * ? diff --git a/deploy/offline/.env.iw b/deploy/offline/.env.iw index 94bd4d5..59946d0 100644 --- a/deploy/offline/.env.iw +++ b/deploy/offline/.env.iw @@ -59,4 +59,4 @@ MESHSAFE_POLL_CRON=0/10 * * * * ? TZ=Asia/Shanghai APP_JAVA_OPTS=-Xms1g -Xmx3g -Dfile.encoding=UTF-8 REDIS_MAXMEMORY=512mb -FILE_TRANSFER_MONITOR_CRON=0 */1 * * * ? +FILE_TRANSFER_MONITOR_CRON=0/5 * * * * ? diff --git a/deploy/offline/.env.ow b/deploy/offline/.env.ow index e0fb0d1..3ae7ac8 100644 --- a/deploy/offline/.env.ow +++ b/deploy/offline/.env.ow @@ -58,4 +58,4 @@ MESHSAFE_POLL_CRON=0/10 * * * * ? TZ=Asia/Shanghai APP_JAVA_OPTS=-Xms1g -Xmx3g -Dfile.encoding=UTF-8 REDIS_MAXMEMORY=512mb -FILE_TRANSFER_MONITOR_CRON=0 */1 * * * ? +FILE_TRANSFER_MONITOR_CRON=0/5 * * * * ? diff --git a/deploy/offline/docker-compose.yml b/deploy/offline/docker-compose.yml index 4f6eecf..6270dc4 100644 --- a/deploy/offline/docker-compose.yml +++ b/deploy/offline/docker-compose.yml @@ -76,7 +76,7 @@ services: FILE_TRANSFER_LOCATION: "${SFILE_TRANSFER_LOCATION:?缺少 SFILE_TRANSFER_LOCATION}" FILE_TRANSFER_SEND_DIR: /data/transfer/send FILE_TRANSFER_RECEIVE_DIR: /data/transfer/receive - FILE_TRANSFER_MONITOR_CRON: "${FILE_TRANSFER_MONITOR_CRON:-0 */1 * * * ?}" + FILE_TRANSFER_MONITOR_CRON: "${FILE_TRANSFER_MONITOR_CRON:-0/5 * * * * ?}" MESHSAFE_ENABLED: ${MESHSAFE_ENABLED:-true} MESHSAFE_BASE_URL: ${MESHSAFE_BASE_URL:-} diff --git a/deploy/offline/部署说明.md b/deploy/offline/部署说明.md index a598569..2eaf66a 100644 --- a/deploy/offline/部署说明.md +++ b/deploy/offline/部署说明.md @@ -212,7 +212,7 @@ docker exec -i sfile-iw-pg psql -U sfile -d s_file < upgrade-20261101-meshsafe-f 7. **MeshSafe 凭证**:`MESHSAFE_CLIENT_ID`/`SECRET` 必须在 MeshSafe 侧 `MESHSAFE_API_CLIENTS` 白名单里存在,否则送检全部 401。`MESHSAFE_FAIL_OPEN=true` 时检测服务挂了不阻断业务(只记失败),等保从严请置 `false`。 8. **`host.docker.internal` 需要 Docker ≥ 20.10**;MeshSafe 在独立服务器时不需要它,可把 compose 里那两行 `extra_hosts` 删掉。 9. **PDF 盖章依赖 spire.pdf 是桩实现**:本机因拿不到商业包做了替代 jar,运行时调用会抛 `UnsupportedOperationException`。交付前若客户要电子签章功能,必须换回 `e-iceblue:spire.pdf:3.7.4` 正式包重新打 jar。 -10. **摆渡延迟固定为监听周期**(默认 1 分钟一次)。客户嫌慢就调 `FILE_TRANSFER_MONITOR_CRON`,不要改成秒级——它会整目录扫描。 +10. **端到端延迟里有一半是监听周期带来的空等**。收发两侧各轮询一次,默认 5 秒一轮 → 平均空等 5 秒、最坏 10 秒(早期默认 1 分钟时是平均 60 秒、最坏 120 秒,这是"一页文件也要 2 分钟"的主因)。客户嫌慢就调 `FILE_TRANSFER_MONITOR_CRON`;**改成秒级是安全的**:空目录一轮只有两次 `Files.list` + 过滤,开销可忽略,且 Spring 的 cron 任务要等上一轮跑完才排下一轮,同一实例内不会重叠。唯一副作用是**损坏的包会被更频繁地重试**(失败包当前既不删除也不改名,mtime 最老所以每轮都排第一),目录里若长期堆积坏包,把周期调回分钟级或先清掉坏包。 11. **两侧数据库完全独立**,同一份 `init-data.sql` 灌出来 admin 初始口令一致,交付时两侧都要改。 12. **装完才发现角色装反了**(内网机上跑了 `install.sh ow`):`.env` 与参数角色不一致时 `install.sh` 直接拒绝,所以真发生一定是 `rm .env` 之后重装。compose 项目名跟着角色走,旧项目还在占用 `APP_SUBNET`,会报 `invalid pool request: Pool overlaps with other one on this address space`。先把旧项目拆掉再起: `docker compose -p sfile-<旧角色> down` → `rm .env` → `./scripts/install.sh <正确角色>`。