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

如何在API路由与getServerSideProps之间共享带TTL的缓存数据

方案1:使用Next.js内置缓存(优先推荐)

Next.js原生提供了跨服务端上下文的全局缓存能力,无需额外依赖,性能最优:

  • App Router场景:直接调用原生fetch请求外部API,设置next.revalidate参数为你的ttl值即可,缓存自动全局共享,在Server Components、Route Handler、服务端函数中调用同个接口会复用缓存,到期自动失效。
  • Pages Router场景:用unstable_cache封装请求逻辑,示例代码:
import { unstable_cache } from 'next/cache'

const getX = unstable_cache(
  async () => {
    const res = await fetch('外部API地址')
    return res.json()
  },
  ['unique-key-for-data-x'], // 唯一缓存键
  { revalidate: 你的ttl秒数 }
)

封装完成后直接在getServerSideProps和API路由中调用getX()即可,自动实现按需拉取、ttl失效、全局缓存共享。

方案2:全局单例LRU缓存(适用于自托管单实例部署)

你之前用类静态属性失效的核心原因是Next.js的模块加载机制,不同服务端上下文加载模块时可能生成独立的类实例,通过将缓存挂载到全局对象可以规避这个问题:
首先安装轻量内存缓存库lru-cache,然后封装工具函数:

import LRU from 'lru-cache'

// 挂载到globalThis避免模块隔离/热重载导致的多实例问题
const globalCache = globalThis as unknown as { xCache: LRU<string, any> }

if (!globalCache.xCache) {
  globalCache.xCache = new LRU({
    max: 1,
    ttl: 你的ttl秒数 * 1000
  })
}

const cache = globalCache.xCache

export async function getX() {
  let x = cache.get('x')
  if (!x) {
    x = await fetch('外部API地址').then(res => res.json())
    cache.set('x', x)
  }
  return x
}

该方案纯内存读写,性能和你最初的类静态属性方案一致,解决了实例隔离问题。

方案3:轻量内存存储(适用于多实例/Serverless部署)

如果你的服务部署在多worker、多实例或者Vercel这类Serverless环境,进程内内存本身无法跨实例共享,建议使用本地Redis或者SQLite作为缓存层:SQLite走本地IO性能远高于直接读写普通文本文件,Redis为纯内存操作延迟极低,完全可以满足性能要求。

内容的提问来源于stack exchange,提问作者jannis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:36:02