ExpressJS 如何实现按需缓存并支持手动触发缓存更新?
方案推荐
你需要的可控失效的内存缓存完全可以不用外部服务,下面是两种可直接落地的实现方案:
方案1:原生实现(无需额外npm包)
你要的基于版本key的缓存逻辑非常简单,几十行代码就能实现,完全匹配你的需求:
// 全局缓存配置 const playerCache = { data: null, cacheVersion: 0 // 版本key,只要修改该值就会触发缓存失效 } // 原有30秒更新资产price的定时任务 setInterval(async () => { // 保留原有更新资产的业务逻辑 await batchUpdateAssetsPrice() // 资产更新后触发缓存失效 playerCache.cacheVersion += 1 playerCache.data = null }, 30 * 1000)
修改GET /api/players接口逻辑:
app.get('/api/players', async (req, res) => { // 存在缓存直接返回 if (playerCache.data) { return res.json(playerCache.data) } // 无缓存时查询数据库 const playerData = await Player.findAll({ include: Asset }) // 写入缓存 playerCache.data = playerData res.json(playerData) })
修改POST /api/assets接口逻辑,创建资产后触发缓存失效:
app.post('/api/assets', async (req, res) => { // 保留原有创建资产的业务逻辑 await Asset.create(req.body) // 触发缓存失效 playerCache.cacheVersion += 1 playerCache.data = null res.sendStatus(201) })
方案2:使用成熟npm包(适合后续扩展)
如果你需要缓存大小限制、兜底过期时间、多缓存键管理等更完善的能力,推荐使用lru-cache,这是Node.js生态应用最广的内存缓存库,无任何外部依赖:
- 安装依赖
npm install lru-cache - 使用示例
const LRU = require('lru-cache') // 初始化缓存 const apiCache = new LRU({ max: 50, // 最多缓存50条数据,避免内存溢出 ttl: 35 * 1000 // 兜底35秒过期,即使手动失效逻辑异常也能自动更新数据 }) // 固定玩家接口的缓存key const PLAYER_DATA_KEY = 'players_with_assets' // GET接口逻辑 app.get('/api/players', async (req, res) => { const cached = apiCache.get(PLAYER_DATA_KEY) if (cached) return res.json(cached) const playerData = await Player.findAll({ include: Asset }) apiCache.set(PLAYER_DATA_KEY, playerData) res.json(playerData) }) // 在POST接口、30秒定时任务中需要失效缓存时,直接删除对应key即可 apiCache.delete(PLAYER_DATA_KEY)
注意:上述两种内存缓存方案都仅适合单实例部署场景,服务重启后缓存会自动清空,不会出现数据异常问题。如果你的服务是多实例部署,才需要引入Redis做全局统一缓存,避免多实例数据不一致。
内容的提问来源于stack exchange,提问作者CyberCitizen01
相关产品推荐
相关产品推荐

