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

缩略图架构:异步生成 + 同步兜底 + 后端中转缓存

文件缩略图覆盖图片、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_statusthumbnail_retry_count 字段。
  • 缩略图不变,缓存命中后零后端负载。但 FAILED 重试恢复后 objectKey 不变内容变,浏览器会命中旧占位图缓存。对策:占位图(PENDING/FAILED/UNSUPPORTED)返回时设 Cache-Control: no-cache;真缩略图(READY)返回时设 max-age=86400。占位图不被强缓存,真缩略图一旦就绪即被缓存住。