修复主站通道引用被误清空导致任务状态永久卡住
问题:主站重连期间节点先后认证多条通道,引用被最后一条覆盖;那条通道断开后 引用被清空,而更早建立、仍然可用的通道继续发送可用性探测。节点因引用为空不再 上报任何任务状态,主站又能在旧通道上收到探活响应,双方都判定连接正常。于是 未完成任务永久停在「已提交」,只有人工触发重连或重启主站才会恢复。 现场证据:gid 4203383 于 19:31 创建、19:32 归档完成,节点此后每 5 秒扫到 status=4,却再未打印过「任务状态发送完成」;主站侧 17:23 之后一条「下载进度」 都没有。20:28/20:29 两次收到任务下发时节点判定 server 为空而静默丢弃。 修复: - 新增 PrimaryChannelTracker 统一管理主站通道引用,并保留全部已认证通道。 首选通道失效时立即回退到其它仍可用的已认证通道;引用被清空时,已认证通道上 的下一条消息即可恢复它。认领口径严格等于主站实际会发的消息类型(身份/任务下发/ 删除/探活/订阅快照),备机身份与节点自身出站类型都不算证据。 - 新增 RekickPolicy:有待上报任务却无可用通道时,以 30 秒为限流间隔主动重新 唤起主站,不再干等最长半小时的探测周期。阻塞式探测投递到独立线程,避免占用 5 秒调度线程拖住下载扫描与压缩。 - 通道不可用时的告警与重连判断放在 downloadCheck 之前,但不提前返回, 本地下载与压缩必须继续推进;否则正在下载、进度无变化的任务会走「无需上报」 的提前返回路径,通道失联后既不告警也不重连,正是历史事故的成因。 验证:新增 13 项测试(通道引用自愈 6、事故场景复现 3、重连限流 4), 节点侧合计 28 项全绿。已部署到存储节点并与主站重新握手,双向报文正常, 未完成任务数归零。
This commit is contained in:
+15
-2
@@ -45,13 +45,15 @@ storageNode/
|
||||
│ │ │ └── ResponseMessage.java # 通用响应(type=0)
|
||||
│ │ └── Service/
|
||||
│ │ ├── DeleteService.java # 删除画廊目录
|
||||
│ │ └── DownloadCheckService.java # 下载监控与压缩服务
|
||||
│ │ ├── DownloadCheckService.java # 下载监控与压缩服务
|
||||
│ │ ├── PrimaryChannelTracker.java # 主站通道引用登记与自愈
|
||||
│ │ └── RekickPolicy.java # 主动重新唤起主站的限流判定
|
||||
│ └── resources/
|
||||
│ ├── config.properties # DouNai 订阅地址配置
|
||||
│ ├── simplelogger.properties # SLF4J 日志配置(输出到 run.out)
|
||||
│ └── reflect-config.json # GraalVM 反射配置(Jackson 序列化)
|
||||
└── test/
|
||||
└── java/ # 订阅快照与下载/压缩恢复测试
|
||||
└── java/ # 订阅快照、下载/压缩恢复与主站通道自愈测试
|
||||
```
|
||||
|
||||
---
|
||||
@@ -130,6 +132,17 @@ storageNode/
|
||||
- 按名称删除画廊目录
|
||||
- 失败时返回 `ErrorCode.IO_ERROR` 或 `ErrorCode.FILE_NOT_FOUND`
|
||||
|
||||
### PrimaryChannelTracker
|
||||
- 登记「哪条通道是主站」,供任务状态上报与心跳使用
|
||||
- 只有主站会发的消息类型(身份/任务下发/探活/订阅快照)才可用于认领引用;
|
||||
备机的身份消息与节点自己的出站类型都不算证据
|
||||
- 首选通道断开时立即回退到其它仍可用的已认证通道;引用被清空时,
|
||||
已认证通道上的下一条消息即可恢复它,避免任务状态静默停止上报
|
||||
|
||||
### RekickPolicy
|
||||
- 判定「有待上报任务、却无可用通道」时是否应主动重新唤起主站
|
||||
- 以 30 秒为最小间隔限流,既能快速自愈,又不会在主站确实离线时形成重连风暴
|
||||
|
||||
---
|
||||
|
||||
## 配置说明
|
||||
|
||||
Reference in New Issue
Block a user