Next.js中使用node-cache缓存API时如何适配后端月度更新优化缓存策略
解决方案
以下是不同实现成本的优化方案,按优先级从高到低排序:
方案1:后端配合推送更新通知(最优,无多余请求)
- 对接后端团队,在导航、页脚数据更新时,后端主动调用你Next.js服务暴露的专属缓存清理接口
- 你只需新增一个带权限校验的接口路由,逻辑为执行
myCache.del("navigation")和myCache.del("footer")清空对应缓存 - 缓存过期时间可直接设置为30天甚至更长,仅收到更新通知时才会清空缓存重新拉取数据,完全无冗余请求
方案2:用HTTP缓存校验头实现轻量验新(无需后端额外开发接口)
- 绝大多数后端接口默认会返回
ETag或者Last-Modified标准响应头,你可以将这两个值和业务数据一同存入缓存 - 可保留原过期逻辑或直接拉长过期时间,每次读取缓存时额外向后端接口发起
HEAD请求,携带If-None-Match(对应ETag值)、If-Modified-Since(对应Last-Modified值)请求头 - 若接口返回304状态码,说明数据未更新,直接返回本地缓存;若返回200状态码,再更新缓存中的业务数据和对应缓存头即可
- 该方案的请求无返回体,开销远低于全量拉取接口,就算将校验频率调整为每天1次,资源消耗也可忽略不计
方案3:长过期+手动触发更新(最低成本,无需后端配合)
- 直接将缓存过期时间从3600秒改为2592000秒(30天)
- 在内部运维后台新增一个手动清理缓存的按钮,每次收到后端/运营的更新通知时,点击按钮清空对应缓存即可
- 若没有内部后台,也可以临时新增一个带鉴权的清理接口,收到更新通知时手动调用即可
方案4:复用Next.js原生ISR能力(符合Next.js最佳实践)
- 若这部分数据用于页面渲染,可无需自行维护node-cache,直接使用Next.js的增量静态再生能力,设置
revalidate: 2592000,同时暴露revalidate接口,后端更新数据时调用接口触发页面重新生成即可,比自行维护缓存稳定性更高
方案2参考实现代码
const NodeCache = require("node-cache"); const axios = require("axios"); const myCache = new NodeCache(); const TARGET_API = "你的后端接口地址"; // 缓存结构调整为包含业务数据和缓存校验头的对象 async function getNavAndFooter() { const cacheData = myCache.get("navFooter"); const headers = {}; if (cacheData) { // 存在缓存时携带校验头发起请求 if (cacheData.etag) headers["If-None-Match"] = cacheData.etag; if (cacheData.lastModified) headers["If-Modified-Since"] = cacheData.lastModified; } try { const res = await axios.get(TARGET_API, { headers, validateStatus: status => status === 200 || status === 304 }); // 304状态代表数据未更新,直接返回缓存 if (res.status === 304) { return { navigation: cacheData.navigation, footer: cacheData.footer } } // 数据更新时重写缓存 const newCacheData = { navigation: res.data['navigation-menu'], footer: res.data['footer-menu'], etag: res.headers.etag, lastModified: res.headers['last-modified'] } myCache.set("navFooter", newCacheData, 2592000); return { navigation: newCacheData.navigation, footer: newCacheData.footer } } catch (e) { // 接口异常时优先降级返回旧缓存,无缓存再抛出异常 if (cacheData) { return { navigation: cacheData.navigation, footer: cacheData.footer } } throw e; } }
内容的提问来源于stack exchange,提问作者amin71
相关产品推荐
相关产品推荐

