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

Next.js服务端node-cache跨API无法共享缓存问题求助

Next.js中node-cache跨API路由无法共享缓存的解决方法

问题原因

你遇到的问题本质是node-cache属于内存级缓存,在Next.js的运行环境中无法跨请求或跨实例共享,具体分两种场景:

  1. 开发模式:Next.js的热重载机制会在代码变动时重新加载模块,每次请求可能生成新的Cache实例,导致缓存无法持久化。
  2. 生产Serverless模式:如果部署在Vercel、Netlify这类Serverless平台,每个API请求可能被分配到不同的函数实例,每个实例有独立的内存空间,缓存无法跨实例共享。

另外可以先快速排查:API1存入的URL键和API2查询的URL是否完全一致(比如大小写、末尾斜杠、参数编码等细节),不过从你日志里API2的Cache.keys()为空来看,大概率是实例不共享的问题。

解决方案

方案一:用单例模式确保Cache实例唯一(解决开发模式问题)

修改你的cache.ts,改用单例模式创建Cache,避免热重载时重复创建实例:

import NodeCache from 'node-cache';

let cacheInstance: NodeCache | undefined;

export default function getCache() {
  if (!cacheInstance) {
    cacheInstance = new NodeCache({ stdTTL: 60 * 60 * 6 }); // 6小时
  }
  return cacheInstance;
}

然后在API1和API2中这样使用:

// API1中
import getCache from '@/utils/cache';
const Cache = getCache();

// API2中同理
import getCache from '@/utils/cache';
const Cache = getCache();

方案二:改用外部缓存服务(解决生产Serverless场景)

如果是生产环境的Serverless部署,内存缓存根本无法跨实例共享,必须用外部缓存服务,比如Redis、Vercel KV等。这里以Redis为例:

  1. 安装依赖:
npm install redis
  1. 创建新的cache.ts:
import { createClient } from 'redis';

// 从环境变量读取Redis连接地址
const redisClient = createClient({
  url: process.env.REDIS_URL
});

// 连接Redis,捕获错误
redisClient.connect().catch(err => console.error('Redis连接失败:', err));

// 获取缓存
export async function getCachedValue<T>(key: string): Promise<T | null> {
  try {
    const value = await redisClient.get(key);
    return value ? JSON.parse(value) : null;
  } catch (err) {
    console.error('获取缓存失败:', err);
    return null;
  }
}

// 设置缓存(带过期时间)
export async function setCachedValue<T>(key: string, value: T): Promise<void> {
  try {
    await redisClient.setEx(key, 60 * 60 * 6, JSON.stringify(value));
  } catch (err) {
    console.error('设置缓存失败:', err);
  }
}
  1. 在API1和API2中使用:
// API1中
import { getCachedValue, setCachedValue } from '@/utils/cache';

async function fetchFromUrl(url: string): Promise<UrlContent | null> {
  const cachedContent = await getCachedValue<UrlContent>(url);
  if (cachedContent) {
    return cachedContent;
  }

  // ... 你的计算逻辑 ...

  await setCachedValue(url, cleanedContent);
  return cleanedContent;
}

额外检查项

确认API1存入的URL和API2查询的URL完全一致:

  • 有没有大小写差异(比如https://Example.com和https://example.com是不同的键)
  • 末尾是否有斜杠(比如/api/data和/api/data/)
  • URL参数的顺序是否一致(比如?a=1&b=2和?b=2&a=1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:45:11