From c9553ff4974b333957dbde31ea731b382409ea08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=BB=E5=8B=87=E7=A5=A5?= <237899745@qq.com> Date: Tue, 11 Nov 2025 14:19:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=88=86=E4=BA=AB=E7=BC=93=E5=AD=98=E8=BF=87=E6=9C=9F=E6=9C=BA?= =?UTF-8?q?=E5=88=B6(TTL)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题描述: - 分享文件缓存使用Map没有过期机制 - 缓存会无限增长,占用内存 - 文件更新或删除后缓存不会自动清除 - 长期运行可能导致内存泄漏 修复内容: 1. 实现TTLCache类 - 支持自定义过期时间(默认1小时) - 自动检查缓存是否过期 - API完全兼容Map(set/get/has/delete) 2. 添加自动清理机制 - 每10分钟自动清理过期缓存 - 记录清理日志便于监控 - 提供destroy方法停止清理定时器 3. 替换shareFileCache为TTLCache实例 - 设置1小时TTL - 无需修改现有代码 - 向后兼容所有现有使用 缓存特性: - get()时自动检查过期 - has()时自动检查过期 - 定期清理避免内存积累 - size()方法获取当前缓存数量 影响范围: 分享文件缓存管理 测试建议: - 验证分享链接访问后缓存生效 - 验证1小时后缓存自动失效 - 监控日志确认定期清理执行 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- backend/server.js | 88 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/backend/server.js b/backend/server.js index feeb459..b720b78 100644 --- a/backend/server.js +++ b/backend/server.js @@ -63,9 +63,91 @@ const upload = multer({ limits: { fileSize: 5 * 1024 * 1024 * 1024 } // 5GB限制 }); -// 分享文件信息缓存(内存缓存) -// 格式: Map -const shareFileCache = new Map(); +// ===== TTL缓存类 ===== + +// 带过期时间的缓存类 +class TTLCache { + constructor(defaultTTL = 3600000) { // 默认1小时 + this.cache = new Map(); + this.defaultTTL = defaultTTL; + + // 每10分钟清理一次过期缓存 + this.cleanupInterval = setInterval(() => { + this.cleanup(); + }, 10 * 60 * 1000); + } + + set(key, value, ttl = this.defaultTTL) { + const expiresAt = Date.now() + ttl; + this.cache.set(key, { value, expiresAt }); + } + + get(key) { + const item = this.cache.get(key); + if (!item) { + return undefined; + } + + // 检查是否过期 + if (Date.now() > item.expiresAt) { + this.cache.delete(key); + return undefined; + } + + return item.value; + } + + has(key) { + const item = this.cache.get(key); + if (!item) { + return false; + } + + // 检查是否过期 + if (Date.now() > item.expiresAt) { + this.cache.delete(key); + return false; + } + + return true; + } + + delete(key) { + return this.cache.delete(key); + } + + // 清理过期缓存 + cleanup() { + const now = Date.now(); + let cleaned = 0; + + for (const [key, item] of this.cache.entries()) { + if (now > item.expiresAt) { + this.cache.delete(key); + cleaned++; + } + } + + if (cleaned > 0) { + console.log(`[缓存清理] 已清理 ${cleaned} 个过期的分享缓存`); + } + } + + // 获取缓存大小 + size() { + return this.cache.size; + } + + // 停止清理定时器 + destroy() { + if (this.cleanupInterval) { + clearInterval(this.cleanupInterval); + } + } +} + +// 分享文件信息缓存(内存缓存,1小时TTL) +const shareFileCache = new TTLCache(60 * 60 * 1000); // ===== 工具函数 =====