You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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生态应用最广的内存缓存库,无任何外部依赖:

  1. 安装依赖
    npm install lru-cache
  2. 使用示例
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 01:36:10