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.
1.9 KiB
1.9 KiB
缩略图架构:异步生成 + 同步兜底 + 后端中转缓存
文件缩略图覆盖图片、PDF、Office 三类。采用混合生成策略:上传后异步生成 + 首次请求同步兜底,两路加分布式锁防重复。缩略图存 MinIO 同 bucket(thumbnails/{fileId}.jpg),通过后端 API 中转返回 + Cache-Control: max-age=86400 强缓存,浏览器不直接接触 MinIO。渲染引擎选 LibreOffice headless(Office)+ PDFBox(PDF)+ Java ImageIO(图片),部署在 Docker 镜像中。失败重试 3 次标记 FAILED,定时任务扫描重试;非视觉文件前置标记 UNSUPPORTED 跳过。
Considered Options
- 纯懒生成(首次请求同步):无后台任务,第一个请求者等待。简单但首次体验差。
- 纯异步生成:上传后后台任务跑,未就绪时返回占位图。需要前端处理两态,冷数据浪费资源。
- presigned URL 直返:前端直接从 MinIO 拉缩略图。违反"MinIO 不暴公网"铁则。
Consequences
- Docker 镜像体积增加约 400-500MB(LibreOffice headless)。
- 需要 Redis 分布式锁(已有 Redis 基础设施)。锁 TTL 可配置(
crm.file.thumbnail.lock-ttl,默认 150s),必须大于 LibreOffice 转换超时(office-convert-timeout默认 120s),否则慢渲染期间锁过期导致并发重复生成。 - webp 依赖运行时 ImageIO reader 可用性探测,无插件时落
UNSUPPORTED(避免生成必然失败被定时任务无限重试)。 FileInfo表新增thumbnail_status和thumbnail_retry_count字段。- 缩略图不变,缓存命中后零后端负载。但
FAILED重试恢复后 objectKey 不变内容变,浏览器会命中旧占位图缓存。对策:占位图(PENDING/FAILED/UNSUPPORTED)返回时设Cache-Control: no-cache;真缩略图(READY)返回时设max-age=86400。占位图不被强缓存,真缩略图一旦就绪即被缓存住。