5.9 KiB
5.9 KiB
PDF接口文档下载缓存优化说明
📋 概述
本次优化为PDF接口文档下载功能添加了本地文件缓存机制,显著提升了下载性能,减少了重复生成PDF的开销。
🔍 问题分析
原有问题
-
性能问题:
- 每次请求都重新生成PDF,没有缓存机制
- PDF生成涉及复杂的字体加载、页面构建、表格渲染等操作,耗时较长
- 同一产品的PDF被多次下载时,会重复执行相同的生成过程
-
资源浪费:
- CPU资源浪费在重复的PDF生成上
- 数据库查询重复执行
- 没有版本控制,即使产品文档没有变化,也会重新生成
✅ 解决方案
1. PDF缓存管理器 (PDFCacheManager)
创建了专门的PDF缓存管理器,提供以下功能:
- 本地文件缓存:将生成的PDF文件保存到本地文件系统
- 版本控制:基于产品ID和文档版本号生成缓存键,确保版本更新时自动失效
- 自动过期:支持TTL(Time To Live)机制,自动清理过期缓存
- 大小限制:支持最大缓存大小限制,防止磁盘空间耗尽
- 定期清理:后台任务每小时自动清理过期文件
2. 缓存键生成策略
// 基于产品ID和文档版本号生成唯一的缓存键
cacheKey = MD5(productID + ":" + version)
- 当产品文档版本更新时,自动生成新的缓存
- 旧版本的缓存会在过期后自动清理
3. 缓存流程
请求下载PDF
↓
检查缓存是否存在且有效
↓
├─ 缓存命中 → 直接返回缓存的PDF文件
└─ 缓存未命中 → 生成PDF → 保存到缓存 → 返回PDF
4. 集成到下载接口
修改了 DownloadProductDocumentation 方法:
- 缓存优先:首先尝试从缓存获取PDF
- 异步保存:生成新PDF后异步保存到缓存,不阻塞响应
- 缓存标识:响应头中添加
X-Cache: HIT/MISS标识,便于监控
🚀 性能提升
预期效果
- 首次下载:与之前相同,需要生成PDF(约1-3秒)
- 后续下载:直接从缓存读取(< 100ms),性能提升 10-30倍
- 缓存命中率:对于热门产品,缓存命中率可达 80-90%
响应时间对比
| 场景 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 首次下载 | 1-3秒 | 1-3秒 | - |
| 缓存命中 | 1-3秒 | < 100ms | 10-30倍 |
| 版本更新后首次 | 1-3秒 | 1-3秒 | - |
⚙️ 配置说明
环境变量配置
可以通过环境变量自定义缓存配置:
# 缓存目录(默认:系统临时目录下的tyapi_pdf_cache)
export PDF_CACHE_DIR="/path/to/cache"
# 缓存过期时间(默认:24小时)
export PDF_CACHE_TTL="24h"
# 最大缓存大小(默认:500MB)
export PDF_CACHE_MAX_SIZE="524288000" # 字节
默认配置
- 缓存目录:系统临时目录下的
tyapi_pdf_cache - TTL:24小时
- 最大缓存大小:500MB
📁 文件结构
tyapi-server/
├── internal/
│ └── shared/
│ └── pdf/
│ ├── pdf_cache_manager.go # 新增:PDF缓存管理器
│ ├── pdf_generator.go # 原有:PDF生成器
│ └── ...
├── internal/
│ └── infrastructure/
│ └── http/
│ └── handlers/
│ └── product_handler.go # 修改:集成缓存机制
└── internal/
└── container/
└── container.go # 修改:初始化缓存管理器
🔧 使用示例
基本使用
缓存机制已自动集成,无需额外代码:
// 用户请求下载PDF
GET /api/v1/products/{id}/documentation/download
// 系统自动:
// 1. 检查缓存
// 2. 缓存命中 → 直接返回
// 3. 缓存未命中 → 生成PDF → 保存缓存 → 返回
手动管理缓存
如果需要手动管理缓存(如产品更新后清除缓存):
// 使特定产品的缓存失效
cacheManager.InvalidateByProductID(productID)
// 使特定版本的缓存失效
cacheManager.Invalidate(productID, version)
// 清空所有缓存
cacheManager.Clear()
// 获取缓存统计信息
stats, _ := cacheManager.GetCacheStats()
📊 监控和日志
日志输出
系统会记录以下日志:
- 缓存命中:
PDF缓存命中- 包含产品ID、版本、文件大小 - 缓存未命中:
PDF缓存未命中,开始生成PDF - 缓存保存:
PDF已缓存- 包含产品ID、缓存键、文件大小 - 缓存清理:
已清理过期缓存文件- 包含清理数量和释放空间
响应头标识
响应头中添加了缓存标识:
X-Cache: HIT- 缓存命中X-Cache: MISS- 缓存未命中
🔒 安全考虑
- 文件权限:缓存文件权限设置为
0644,仅所有者可写 - 目录隔离:缓存文件存储在独立目录,不影响其他文件
- 自动清理:过期文件自动清理,防止磁盘空间耗尽
🐛 故障处理
缓存初始化失败
如果缓存管理器初始化失败,系统会:
- 记录警告日志
- 继续正常运行(禁用缓存功能)
- 所有请求都会重新生成PDF
缓存读取失败
如果缓存读取失败,系统会:
- 记录警告日志
- 自动降级为重新生成PDF
- 不影响用户体验
🔄 后续优化建议
- 分布式缓存:考虑使用Redis等分布式缓存,支持多实例部署
- 缓存预热:在系统启动时预生成热门产品的PDF
- 压缩存储:对PDF文件进行压缩存储,节省磁盘空间
- 缓存统计:添加更详细的缓存统计和监控指标
- 智能清理:基于LRU等算法,优先清理不常用的缓存
📝 更新日志
- 2024-12-XX:初始版本,实现本地文件缓存机制
- 添加PDF缓存管理器
- 集成到下载接口
- 支持版本控制和自动过期