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

如何在Next.js全应用及API侧保持对象存活,实现全局singleton单例?

Next.js全局单例实例复用解决方案

问题本质

Next.js 无状态的运行机制导致普通ES模块单例失效:热重载、Serverless函数冷启动、模块隔离等场景会清空模块缓存,每次导入都会触发新实例初始化。

方案1:基于global对象的缓存实现(最通用)

Node.js环境下global为进程级全局唯一对象,进程不重启就不会被重置,直接将单例挂载到global上即可避免重复初始化:

// lib/my-singleton.ts
// 自定义业务类,可替换为数据库客户端、第三方SDK实例等任意需要复用的对象
class MyBusinessService {
  constructor() {
    // 初始化逻辑仅执行一次
    console.log('单例实例初始化')
  }

  // 自定义业务方法
  addCount() {
    this.count++
    return this.count
  }

  private count = 0
}

let instance: MyBusinessService

if (process.env.NODE_ENV === 'production') {
  // 生产环境直接初始化一次
  instance = new MyBusinessService()
} else {
  // 开发环境适配热重载,挂载到global避免重复创建
  const globalKey = Symbol.for('my_business_service_singleton')
  if (!(global as any)[globalKey]) {
    (global as any)[globalKey] = new MyBusinessService()
  }
  instance = (global as any)[globalKey]
}

export default instance

注意事项

  • 仅支持Node.js运行时,Edge Runtime、Cloudflare Workers等无持久进程的边缘环境不适用
  • Serverless部署场景下,平台会根据流量动态扩缩容函数实例,每个新启动的函数实例会初始化一次单例,同一实例处理的所有请求可复用该实例;若需要跨所有实例完全一致的状态,需配合Redis等外部存储做数据同步

方案2:自定义Server启动时初始化(最稳定)

如果使用自定义Node.js Server托管Next.js,可在服务启动阶段直接初始化单例,只要进程不重启,实例就不会被重置:

// server.js
const next = require('next')
const http = require('http')
const MyBusinessService = require('./lib/my-business-service')

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

// 服务启动时全局初始化单例,所有请求复用
global.myBusinessService = new MyBusinessService()

app.prepare().then(() => {
  http.createServer((req, res) => {
    handle(req, res)
  }).listen(3000, () => {
    console.log('> Ready on http://localhost:3000')
  })
})

后续在任意API路由、服务组件中直接通过global.myBusinessService访问即可,不会重复创建实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:06:09