You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

660 lines
34 KiB

1 month ago
# 任务调度
<cite>
**本文引用的文件**
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java)
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
- [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
1 month ago
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [IFileInfoService.java](file://crm-file/src/main/java/com/crm/file/service/IFileInfoService.java)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
1 month ago
- [ThumbnailRenderer.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailRenderer.java)
- [ImageThumbnailRenderer.java](file://crm-file/src/main/java/com/crm/file/service/impl/ImageThumbnailRenderer.java)
- [ThumbnailPlaceholderService.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailPlaceholderService.java)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java)
1 month ago
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
1 month ago
- [ThumbnailDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/ThumbnailDTO.java)
1 month ago
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java)
- [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java)
- [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java)
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java)
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
</cite>
1 month ago
## 更新摘要
**变更内容**
- 新增缩略图异步生成任务(ThumbnailGenerationTask):支持Redis分布式锁、异步渲染、失败重试机制
- 新增缩略图失败重试定时任务(ThumbnailRetryTask):每日凌晨4点自动恢复失败的缩略图生成
- 增强调度配置(SchedulingConfig):启用异步和定时任务支持
- 扩展文件属性配置(FileProperties):新增缩略图相关配置参数
- 完善缩略图状态管理:PENDING、READY、FAILED、UNSUPPORTED状态机
1 month ago
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 引言
1 month ago
本技术文档围绕文件服务的任务调度能力,系统阐述异步任务处理、定时任务调度与清理任务执行等核心功能。重点覆盖孤立分片清理算法、缩略图异步生成、任务状态管理、失败重试机制、任务配置参数与执行频率设置、资源监控与运维要点,以及分布式环境下的任务协调与数据一致性保障。同时提供日志分析、性能监控与故障排查指南,并给出自定义任务开发规范与最佳实践建议,帮助读者快速理解并高效扩展该系统的任务调度能力。
**更新** 新增了缩略图异步生成和失败重试机制,增强了文件预览能力的可靠性和用户体验。
1 month ago
## 项目结构
本项目采用多模块分层组织:
- crm-app:应用启动入口与全局配置
- crm-base:基础能力(通用实体、异常、结果封装、配置、工具类)
- crm-file:文件服务模块,包含文件上传下载、预览、任务调度与清理逻辑
- docs:文档与代理相关说明
关键调度相关位置:
- 调度配置与属性:crm-base 的 ScheduledTaskProperties
1 month ago
- 文件服务调度:crm-file 的 SchedulingConfig、OrphanChunkCleanupTask、ThumbnailGenerationTask、ThumbnailRetryTask
1 month ago
- 文件元数据与持久化:crm-file 的 FileInfo、FileInfoMapper、FileInfoServiceImpl
- 分布式ID生成:crm-base 的 SnowflakeIdWorker、SnowflakeProperties
```mermaid
graph TB
subgraph "应用层"
APP["CrmAppApplication"]
CFG_APP["application.yml"]
end
subgraph "基础能力"
PROP["ScheduledTaskProperties"]
IDW["SnowflakeIdWorker"]
IDP["SnowflakeProperties"]
EXC["GlobalExceptionHandlerAdvice"]
end
subgraph "文件服务"
SCH["SchedulingConfig"]
1 month ago
TASK1["OrphanChunkCleanupTask"]
TASK2["ThumbnailGenerationTask"]
TASK3["ThumbnailRetryTask"]
1 month ago
SVC["FileInfoServiceImpl"]
MAPPER["FileInfoMapper"]
ENT["FileInfo"]
1 month ago
RENDERER["ThumbnailRenderer"]
PLACEHOLDER["ThumbnailPlaceholderService"]
1 month ago
DTO1["UploadSession"]
DTO2["MultipartInitDTO"]
DTO3["FileDownloadDTO"]
DTO4["FileInfoDTO"]
1 month ago
DTO5["ThumbnailDTO"]
1 month ago
CONST["FileConstants"]
1 month ago
FILEPROP["FileProperties"]
1 month ago
end
APP --> CFG_APP
APP --> PROP
APP --> SCH
1 month ago
SCH --> TASK1
SCH --> TASK2
SCH --> TASK3
TASK1 --> SVC
TASK2 --> SVC
TASK3 --> SVC
1 month ago
SVC --> MAPPER
SVC --> ENT
1 month ago
TASK2 --> RENDERER
TASK2 --> PLACEHOLDER
TASK2 --> CONST
TASK2 --> FILEPROP
1 month ago
SVC --> DTO1
SVC --> DTO2
SVC --> DTO3
SVC --> DTO4
1 month ago
SVC --> DTO5
1 month ago
IDW --> IDP
```
**图表来源**
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java)
- [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
1 month ago
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
1 month ago
- [ThumbnailRenderer.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailRenderer.java)
- [ThumbnailPlaceholderService.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailPlaceholderService.java)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java)
- [ThumbnailDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/ThumbnailDTO.java)
1 month ago
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java)
- [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java)
- [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java)
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
**章节来源**
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java)
- [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
1 month ago
## 核心组件
- 调度配置与属性
- ScheduledTaskProperties:集中管理调度开关、线程池、批大小、超时等参数,便于统一治理
1 month ago
- SchedulingConfig:启用并装配定时任务,定义调度策略与执行上下文,支持异步和定时任务
1 month ago
- 清理任务
- OrphanChunkCleanupTask:周期性扫描并清理孤立的上传分片,释放存储与数据库资源
1 month ago
- 缩略图任务
- ThumbnailGenerationTask:异步缩略图生成,支持Redis分布式锁、失败重试、状态管理
- ThumbnailRetryTask:每日凌晨4点扫描失败记录,重置状态并重新提交生成
1 month ago
- 文件服务实现
- FileInfoServiceImpl:文件元数据管理与业务编排,配合 Mapper 完成持久化
- FileInfoMapper:数据访问接口,支撑查询、更新与统计
1 month ago
- 缩略图渲染器
- ThumbnailRenderer:抽象接口,支持图片、PDF、Office等多种格式渲染
- ImageThumbnailRenderer:基于Java ImageIO的图片渲染实现
- ThumbnailPlaceholderService:动态生成文件类型占位图
1 month ago
- 分布式ID
- SnowflakeIdWorker/SnowflakeProperties:提供高并发唯一ID,避免冲突与热点
- 异常与结果封装
- GlobalExceptionHandlerAdvice:统一异常处理,保证任务执行过程中的错误可观测性
- Result/PageResult:标准化返回结构,便于上层消费
1 month ago
**更新** 新增了缩略图相关的任务组件和渲染器,增强了文件预览能力。
1 month ago
**章节来源**
- [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java)
- [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
1 month ago
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
1 month ago
- [ThumbnailRenderer.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailRenderer.java)
- [ImageThumbnailRenderer.java](file://crm-file/src/main/java/com/crm/file/service/impl/ImageThumbnailRenderer.java)
- [ThumbnailPlaceholderService.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailPlaceholderService.java)
1 month ago
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
## 架构总览
1 month ago
整体架构以"配置驱动 + 定时任务 + 服务编排"为核心:
1 month ago
- 应用启动时加载 application.yml 与 ScheduledTaskProperties,初始化调度器与线程池
1 month ago
- SchedulingConfig 注册 OrphanChunkCleanupTask、ThumbnailGenerationTask、ThumbnailRetryTask,按固定频率触发
1 month ago
- 任务执行时通过 FileInfoServiceImpl 与 FileInfoMapper 进行数据扫描与清理
- 使用 SnowflakeIdWorker 生成唯一ID,确保分布式环境下幂等与去重
- 异常由 GlobalExceptionHandlerAdvice 统一捕获并记录,便于追踪
```mermaid
sequenceDiagram
participant App as "应用启动"
participant Prop as "ScheduledTaskProperties"
participant Sch as "SchedulingConfig"
1 month ago
participant Task1 as "OrphanChunkCleanupTask"
participant Task2 as "ThumbnailGenerationTask"
participant Task3 as "ThumbnailRetryTask"
1 month ago
participant Svc as "FileInfoServiceImpl"
participant Map as "FileInfoMapper"
participant DB as "数据库"
App->>Prop : "加载调度配置"
App->>Sch : "注册定时任务"
1 month ago
Sch-->>Task1 : "按周期触发(3 : 00)"
Sch-->>Task2 : "异步触发(上传后)"
Sch-->>Task3 : "按周期触发(4 : 00)"
Task1->>Svc : "调用清理逻辑"
Task2->>Svc : "异步生成缩略图"
Task3->>Svc : "重试失败记录"
Svc->>Map : "查询待处理数据"
1 month ago
Map->>DB : "执行SQL"
DB-->>Map : "返回结果集"
Map-->>Svc : "返回数据"
1 month ago
Svc->>Svc : "处理业务逻辑"
Svc->>Map : "更新状态"
Svc-->>Task1 : "返回清理统计"
Svc-->>Task2 : "返回生成结果"
Svc-->>Task3 : "返回重试结果"
Task1-->>Sch : "记录执行结果"
Task2-->>Sch : "记录执行结果"
Task3-->>Sch : "记录执行结果"
1 month ago
```
**图表来源**
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java)
- [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
1 month ago
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
## 详细组件分析
### 孤立分片清理算法(OrphanChunkCleanupTask)
- 目标:识别并清理未关联到任何有效文件的上传分片,防止存储膨胀与数据不一致
- 输入:分片元数据集合(含会话ID、分片序号、时间戳等)
- 处理流程:
- 批量查询候选分片
- 根据会话有效性、文件完整性校验规则过滤
- 对确认为孤立的分片执行删除操作
- 统计清理数量与耗时,输出日志
- 复杂度与优化:
- 查询阶段采用分页与索引优化,降低全表扫描
- 删除阶段批量提交,减少事务开销
- 支持可配置的批大小与并发度,平衡吞吐与资源占用
```mermaid
flowchart TD
Start(["开始"]) --> LoadCfg["读取调度配置<br/>批大小/超时/并发"]
LoadCfg --> Query["分页查询候选分片"]
Query --> Validate{"会话有效且文件完整?"}
Validate --> |否| MarkOrphan["标记为孤立分片"]
Validate --> |是| Keep["保留分片"]
MarkOrphan --> BatchDelete["批量删除孤立分片"]
Keep --> NextPage{"是否还有下一页?"}
BatchDelete --> NextPage
NextPage --> |是| Query
NextPage --> |否| Stats["统计清理结果"]
Stats --> Log["记录执行日志"]
Log --> End(["结束"])
```
**图表来源**
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
**章节来源**
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
1 month ago
### 缩略图异步生成任务(ThumbnailGenerationTask)
- 目标:异步生成文件缩略图,提升上传响应速度和用户体验
- 核心特性:
- Redis分布式锁:防止重复生成,确保并发安全
- 异步处理:@Async注解保证不阻塞上传链路
- 失败重试:支持配置的重试次数,耗尽后标记FAILED
- 状态管理:PENDING → READY/FAILED/UNSUPPORTED状态机
- 处理流程:
- 获取Redis分布式锁,防止并发重复生成
- 从MinIO拉取原始文件流
- 根据文件类型路由到对应渲染器(图片/PDF/Office)
- 生成缩略图并写回MinIO
- 更新文件状态为READY,重置重试计数
- 失败时递增重试计数,达到限制后标记FAILED
- 配置参数:
- 缩略图尺寸:width=200px, maxHeight=400px
- 重试限制:retryLimit=3次
- 锁超时:lockTtl=150秒(大于最大渲染时间)
- 同步等待:syncWaitTimeout=10秒
```mermaid
flowchart TD
Start(["缩略图生成请求"]) --> GetLock["获取Redis分布式锁"]
GetLock --> LockSuccess{"锁获取成功?"}
LockSuccess --> |否| ReturnFalse["返回false,等待轮询"]
LockSuccess --> |是| CheckStatus["检查文件状态"]
CheckStatus --> StatusValid{"状态为PENDING?"}
StatusValid --> |否| Skip["跳过生成"]
StatusValid --> |是| FindRenderer["查找对应渲染器"]
FindRenderer --> RendererFound{"找到渲染器?"}
RendererFound --> |否| MarkUnsupported["标记UNSUPPORTED"]
RendererFound --> |是| DownloadFile["从MinIO下载原文件"]
DownloadFile --> Render["调用渲染器生成缩略图"]
Render --> UploadThumb["上传缩略图到MinIO"]
UploadThumb --> UpdateReady["更新状态为READY"]
UpdateReady --> ReleaseLock["释放分布式锁"]
ReleaseLock --> Success["返回true"]
MarkUnsupported --> ReleaseLock
Skip --> ReleaseLock
ReturnFalse --> End(["结束"])
Success --> End
```
**图表来源**
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java)
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
**章节来源**
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java)
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
### 缩略图失败重试任务(ThumbnailRetryTask)
- 目标:每日凌晨4点自动扫描并恢复失败的缩略图生成任务
- 处理流程:
- 扫描数据库中thumbnail_status = FAILED的记录
- 将状态重置为PENDING,重试计数归零
- 重新提交异步生成任务
- 记录重试数量和执行情况
- 容错机制:
- 任务自身异常不影响后续执行
- try-catch包裹确保单个记录失败不影响整体任务
- 复用孤儿分片清理任务的健壮模式
```mermaid
flowchart TD
Start(["定时任务触发(4:00)"]) --> QueryFailed["查询FAILED状态的记录"]
QueryFailed --> HasRecords{"有失败记录?"}
HasRecords --> |否| Noop["无操作,结束"]
HasRecords --> |是| ProcessLoop["遍历失败记录"]
ProcessLoop --> ResetStatus["重置状态为PENDING"]
ResetStatus --> ResetCount["重试计数归零"]
ResetCount --> SubmitAsync["提交异步生成任务"]
SubmitAsync --> NextRecord{"还有下一条?"}
NextRecord --> |是| ProcessLoop
NextRecord --> |否| LogComplete["记录执行完成"]
LogComplete --> End(["结束"])
Noop --> End
```
**图表来源**
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
**章节来源**
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
1 month ago
### 任务状态管理与失败重试
- 状态管理:
- 基于 BaseEntity/OwneEntity 的通用字段维护创建时间、更新时间、状态码等
- 结合 Result 与 PageResult 统一封装任务执行结果与分页信息
1 month ago
- 缩略图状态机:PENDING(待生成)、READY(已生成)、FAILED(重试耗尽)、UNSUPPORTED(类型不支持)
1 month ago
- 失败重试:
- 在任务编排层对可重试异常进行捕获与指数退避重试
1 month ago
- 通过 FileProperties 控制最大重试次数、间隔与超时
1 month ago
- 记录重试轨迹与最终失败原因,便于审计与告警
1 month ago
- 定时任务兜底:每日凌晨4点自动重试失败记录
1 month ago
```mermaid
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
+status
}
class OwnedEntity {
+ownerId
+tenantId
}
class FileInfo {
+fileId
+sessionId
+chunkIndex
+size
+md5
1 month ago
+thumbnailStatus
+thumbnailRetryCount
1 month ago
}
class UploadSession {
+sessionId
+totalChunks
+expireAt
}
class MultipartInitDTO {
+sessionId
+fileName
+chunkSize
}
class FileDownloadDTO {
+fileId
+downloadToken
}
class FileInfoDTO {
+fileId
+name
+size
+url
}
1 month ago
class ThumbnailDTO {
+content
+contentType
+cacheable
+statusCode
}
1 month ago
OwnedEntity <|-- BaseEntity
FileInfo --> UploadSession : "关联会话"
FileInfo --> MultipartInitDTO : "初始化参数"
FileInfo --> FileDownloadDTO : "下载响应"
FileInfo --> FileInfoDTO : "信息展示"
1 month ago
FileInfo --> ThumbnailDTO : "缩略图响应"
1 month ago
```
**图表来源**
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java)
- [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java)
- [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java)
1 month ago
- [ThumbnailDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/ThumbnailDTO.java)
1 month ago
**章节来源**
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java)
- [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java)
- [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java)
1 month ago
- [ThumbnailDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/ThumbnailDTO.java)
1 month ago
### 分布式ID与一致性保障
- SnowflakeIdWorker:基于时间戳+机器ID+序列号生成全局唯一ID,避免重复与冲突
- 一致性策略:
- 使用唯一ID作为幂等键,确保任务幂等执行
- 在删除前校验分片归属与会话状态,防止误删
- 通过事务边界包裹批量删除,保证原子性
1 month ago
- Redis分布式锁确保缩略图生成的并发安全
1 month ago
```mermaid
sequenceDiagram
participant Task as "OrphanChunkCleanupTask"
1 month ago
participant ThumbTask as "ThumbnailGenerationTask"
1 month ago
participant Svc as "FileInfoServiceImpl"
participant Map as "FileInfoMapper"
1 month ago
participant Redis as "Redis"
1 month ago
participant DB as "数据库"
Task->>Svc : "请求清理孤立分片"
1 month ago
ThumbTask->>Redis : "获取分布式锁"
Redis-->>ThumbTask : "锁获取结果"
ThumbTask->>Svc : "请求生成缩略图"
1 month ago
Svc->>Map : "查询候选分片(分页)"
Map->>DB : "SELECT ... WHERE ..."
DB-->>Map : "返回分片列表"
Map-->>Svc : "分片集合"
Svc->>Svc : "校验会话与完整性"
Svc->>Map : "DELETE FROM chunk WHERE id IN (...)"
Map->>DB : "执行批量删除"
DB-->>Map : "影响行数"
Map-->>Svc : "删除结果"
Svc-->>Task : "返回统计信息"
1 month ago
ThumbTask->>Svc : "更新缩略图状态"
Svc->>Map : "UPDATE file_info SET status = 'READY'"
Map->>DB : "执行状态更新"
DB-->>Map : "更新结果"
Map-->>Svc : "更新完成"
Svc-->>ThumbTask : "返回生成结果"
ThumbTask->>Redis : "释放分布式锁"
1 month ago
```
**图表来源**
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
1 month ago
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
**章节来源**
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
### 文件预览与外部集成(可选)
- KkFileViewClient:对接第三方预览服务,用于在线预览文件内容
- 在任务或业务流程中按需调用,注意超时与降级策略
**章节来源**
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
## 依赖关系分析
- 模块内依赖:
- OrphanChunkCleanupTask 依赖 FileInfoServiceImpl、FileInfoMapper
1 month ago
- ThumbnailGenerationTask 依赖 FileInfoServiceImpl、ThumbnailRenderer、RedisTemplate
- ThumbnailRetryTask 依赖 FileInfoServiceImpl、ThumbnailGenerationTask
1 month ago
- FileInfoServiceImpl 依赖 FileInfoMapper、常量与DTO
- SchedulingConfig 依赖 ScheduledTaskProperties 与任务类
- 跨模块依赖:
- crm-file 依赖 crm-base 的通用实体、异常、结果封装与ID生成
- 外部依赖:
1 month ago
- 数据库(MyBatis Plus)、对象存储(MinIO)、缓存(Redis)、可能的预览服务(KkFileView)
1 month ago
```mermaid
graph LR
1 month ago
SCH["SchedulingConfig"] --> TASK1["OrphanChunkCleanupTask"]
SCH --> TASK2["ThumbnailGenerationTask"]
SCH --> TASK3["ThumbnailRetryTask"]
TASK1 --> SVC["FileInfoServiceImpl"]
TASK2 --> SVC
TASK3 --> SVC
1 month ago
SVC --> MAP["FileInfoMapper"]
SVC --> ENT["FileInfo"]
1 month ago
SVC --> DTO["UploadSession/MultipartInitDTO/FileDownloadDTO/FileInfoDTO/ThumbnailDTO"]
1 month ago
SVC --> CONST["FileConstants"]
1 month ago
TASK2 --> RENDERER["ThumbnailRenderer"]
TASK2 --> PLACEHOLDER["ThumbnailPlaceholderService"]
TASK2 --> PROP["FileProperties"]
TASK1 --> PROP
TASK3 --> PROP
TASK2 --> REDIS["RedisTemplate"]
1 month ago
SVC --> IDW["SnowflakeIdWorker"]
IDW --> IDP["SnowflakeProperties"]
```
**图表来源**
- [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
1 month ago
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java)
- [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java)
- [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java)
1 month ago
- [ThumbnailDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/ThumbnailDTO.java)
1 month ago
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
1 month ago
- [ThumbnailRenderer.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailRenderer.java)
- [ThumbnailPlaceholderService.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailPlaceholderService.java)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java)
1 month ago
- [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java)
**章节来源**
- [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
- [ThumbnailRetryTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailRetryTask.java)
1 month ago
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
- [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java)
## 性能考虑
- 批处理与分页:
- 合理设置批大小与页大小,避免单次处理过大导致内存与锁竞争
- 并发与线程池:
- 通过 ScheduledTaskProperties 配置线程池容量与队列长度,避免阻塞与溢出
1 month ago
- 缩略图生成使用@Async异步处理,不阻塞主流程
1 month ago
- 索引与SQL优化:
- 针对分片查询条件建立合适索引,减少全表扫描
- 使用批量删除与最小化字段选择提升吞吐
- 超时与熔断:
- 设置合理的任务超时与外部服务超时,防止级联故障
1 month ago
- 缩略图生成设置锁超时和同步等待超时
1 month ago
- 监控指标:
- 记录任务执行时长、成功率、失败率、清理数量、内存与CPU占用
1 month ago
- 监控缩略图生成成功率、重试次数、渲染耗时
- 缓存策略:
- 缩略图支持强缓存(READY状态),减少重复生成
- 分布式锁避免重复计算
1 month ago
1 month ago
**更新** 新增了缩略图相关的性能考虑,包括异步处理、缓存策略和超时配置。
1 month ago
## 故障排查指南
- 常见问题定位:
- 任务未执行:检查 SchedulingConfig 是否启用、cron表达式是否正确、线程池是否耗尽
- 清理不生效:核对查询条件与索引、确认会话有效性判断逻辑、检查事务边界
- 数据不一致:验证幂等键与唯一ID生成、检查删除前的归属校验
1 month ago
- 缩略图生成失败:检查渲染器支持情况、MinIO连接状态、Redis锁获取情况
- 缩略图重试无效:确认FAILED状态记录、检查重试任务执行日志
1 month ago
- 日志与监控:
- 关注任务执行日志中的统计信息与异常堆栈
- 结合数据库慢查询与锁等待信息进行优化
1 month ago
- 监控缩略图生成成功率、重试次数、渲染耗时
1 month ago
- 异常处理:
- GlobalExceptionHandlerAdvice 统一捕获并记录,便于追溯
- BusinessErrorException 用于业务异常,区分系统异常与业务异常
1 month ago
- 缩略图生成异常被捕获并记录,不影响其他任务执行
**更新** 新增了缩略图相关的故障排查指南,包括渲染失败、锁获取失败、重试机制等问题。
1 month ago
**章节来源**
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
## 结论
1 month ago
本任务调度体系以配置驱动与定时任务为核心,结合清晰的分层设计与统一的异常处理,实现了高效的孤立分片清理、稳定的任务执行和可靠的缩略图生成。通过分布式ID、幂等性、事务保障和Redis分布式锁,系统在分布式环境下具备良好的一致性与可靠性。新增的缩略图异步生成和失败重试机制显著提升了文件预览能力和用户体验。建议在运维侧完善监控与告警,持续优化SQL与批处理策略,并遵循自定义任务开发规范,确保扩展任务的稳定性与可维护性。
1 month ago
1 month ago
**更新** 强调了新增缩略图功能对系统整体能力的提升,特别是在用户体验和系统可靠性方面的改进。
1 month ago
## 附录
- 任务配置参数建议:
- 批大小:根据数据量与内存调整,常见范围 100~1000
- 并发度:依据CPU与IO能力设定,避免过度并发
- 超时:设置任务与外部调用的超时阈值,防止长时间阻塞
1 month ago
- 缩略图配置:width=200px, maxHeight=400px, retryLimit=3, lockTtl=150s
1 month ago
- 自定义任务开发规范:
- 使用 ScheduledTaskProperties 统一管理配置
- 实现幂等与重试,记录执行轨迹与统计
- 使用唯一ID与事务保障一致性
- 对外部依赖增加超时与降级策略
1 month ago
- 对于耗时操作使用@Async异步处理
1 month ago
- 最佳实践:
- 优先使用分页与批量操作
- 对热点表建立合适索引
- 定期评估与调整批大小与并发度
- 完善日志与监控,形成闭环
1 month ago
- 合理使用分布式锁避免重复执行
- 设计健壮的失败重试机制
1 month ago
1 month ago
**更新** 新增了缩略图相关的配置参数和最佳实践建议。