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

NextJS 13缓存失效与PM2集群多实例技术咨询

Next.js 13 Server Components 缓存机制与集群模式缓存失效方案

Next.js 13 Server Components 缓存工作机制

Next.js 13的Server Components缓存主要分两类:

  • 静态数据缓存:Server Components里用fetch拉取的静态数据,默认会存在磁盘的.next/cache目录里,属于持久化缓存,默认有效期30天,也能通过revalidate参数自定义过期时间。
  • 动态数据缓存:如果fetch设置了cache: 'no-store'或revalidate: 0,数据不会被缓存;用默认的cache: 'force-cache'或指定revalidate值时,会同时用到内存缓存和磁盘缓存。另外还支持标签缓存,可以给缓存数据打标签,后续通过标签批量失效缓存。

是否属于进程本地缓存?

不全是:

  • 磁盘缓存(.next/cache)是实例共享的,因为存在文件系统里,只要所有PM2实例挂载同一个目录就能访问到。
  • 内存缓存是进程本地的,每个PM2实例都会维护自己的内存缓存副本,这部分不会在实例间共享。

PM2集群模式下批量清除所有实例的缓存标签方案

因为内存缓存是进程本地的,得让每个实例都收到缓存失效的指令,这里给几个实用方法:

方法1:通过PM2进程间通信(IPC)触发

PM2支持集群模式下的进程广播,你可以在Webhook服务里调用PM2 API,给所有集群实例发缓存失效消息:

  • 在Next.js应用里加个IPC监听逻辑,比如在自定义服务器文件(server.js)或中间件里,监听特定消息(比如'clear-cache-tags'),收到后调用revalidateTag()清除对应标签的缓存。
  • Webhook后端用pm2.broadcast()方法,把要清除的标签列表发给所有实例。

示例代码(Next.js端):

// 自定义server.js文件
const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  createServer(async (req, res) => {
    try {
      const parsedUrl = parse(req.url, true);
      await handle(req, res, parsedUrl);
    } catch (err) {
      console.error('处理请求出错', req.url, err);
      res.statusCode = 500;
      res.end('内部服务器错误');
    }
  }).listen(3000, (err) => {
    if (err) throw err;
    console.log('> 服务启动完成:http://localhost:3000');
  });

  // 监听PM2的IPC消息
  process.on('message', (message) => {
    if (message.type === 'clear-cache-tags') {
      const { tags } = message;
      tags.forEach(tag => {
        app.revalidateTag(tag);
        console.log(`进程${process.pid}已清除缓存标签:${tag}`);
      });
    }
  });
});

Webhook端调用PM2广播的示例:

const pm2 = require('pm2');

pm2.connect((err) => {
  if (err) {
    console.error(err);
    process.exit(2);
  }

  // 向所有集群实例广播缓存失效指令
  pm2.broadcast({
    type: 'clear-cache-tags',
    tags: ['product-data', 'user-profile']
  }, (err) => {
    pm2.disconnect();
    if (err) throw err;
  });
});

方法2:用共享存储触发(比如Redis)

借助Redis这类共享存储,让所有实例订阅缓存失效事件:

  • 每个Next.js实例启动一个Redis订阅客户端,监听特定频道(比如nextjs-cache-invalidation)。
  • Webhook后端需要失效缓存时,向Redis频道发布带要清除标签的消息。
  • 每个实例收到消息后,调用revalidateTag()清除对应标签的缓存。

这种方法不依赖PM2的IPC,更适合跨服务器部署的场景。

方法3:重启PM2实例(不推荐)

如果缓存失效频率极低,可以通过Webhook调用pm2 reload <app-name>重启所有实例。但这种方法会导致服务短暂中断,影响用户体验,只适合极端场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:35:31