perf(传输): 摆渡目录监听周期 1 分钟改为 5 秒

端到端延迟里有一半是轮询空等:收发两侧各等一次,1 分钟周期下平均空等
60 秒、最坏 120 秒,这是「一页文件也要 2 分钟」的主因,而真正干活不到 2 秒。

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

部署说明第 10 条原来写「不要改成秒级」,与新默认值矛盾,一并纠正。
This commit is contained in:
KodouWZF
2026-11-03 22:01:25 +08:00
parent 4114c1f434
commit 06fb35b984
6 changed files with 10 additions and 8 deletions

View File

@@ -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 {

View File

@@ -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 * * * * ?

View File

@@ -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 * * * * ?

View File

@@ -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 * * * * ?

View File

@@ -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:-}

View File

@@ -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 <正确角色>`。