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

如何让BullMQ Worker的JS文件在Next.js后端自动运行?

Next.js中BullMQ Worker实例化文件的执行方案

除了在API文件中导入的方式,还有以下几种实用方案:

1. 自定义服务器入口文件(App Router推荐)

如果使用Next.js App Router,可以在项目根目录创建server.ts(或server.js)作为自定义服务器入口,在其中直接导入Worker文件,服务器启动时就会自动初始化Worker。

示例代码:

// server.ts
import { createServer } from 'http';
import { parse } from 'url';
import next from 'next';
// 导入Worker文件,触发实例化
import './lib/workers/email-worker';

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

app.prepare().then(() => {
  createServer((req, res) => {
    const parsedUrl = parse(req.url!, true);
    handle(req, res, parsedUrl);
  }).listen(process.env.PORT || 3000, () => {
    console.log(`> Ready on http://localhost:${process.env.PORT || 3000}`);
  });
});

修改package.json的启动脚本:

{
  "scripts": {
    "dev": "ts-node server.ts",
    "build": "next build",
    "start": "ts-node server.ts"
  }
}

2. 在Middleware中初始化(按需触发)

利用Next.js的Middleware全局拦截特性,在首次请求进入时动态导入Worker文件,确保Worker初始化。注意加单例判断,避免重复执行初始化逻辑。

示例代码:

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

let workerInitialized = false;

export function middleware(request: NextRequest) {
  if (!workerInitialized) {
    // 动态导入Worker文件,仅执行一次
    import('./lib/workers/email-worker');
    workerInitialized = true;
    console.log('Email worker initialized via middleware');
  }
  return NextResponse.next();
}

// 配置Middleware生效范围,比如覆盖所有路由
export const config = {
  matcher: '/:path*',
};

3. 独立进程运行Worker(任务密集场景推荐)

将Worker作为独立进程与Next.js服务器分开运行,避免服务器重启影响Worker运行,也便于单独监控和扩容。

步骤:

  1. 创建单独的Worker启动脚本:
// scripts/start-email-worker.js
const { Worker } = require('bullmq');
const redisConfiguration = require('../lib/config/redis');
const emailWorkerJob = require('../lib/jobs/email-job');

const emailWorker = new Worker("emailSchedule", emailWorkerJob, {
  connection: redisConfiguration
});

emailWorker.on('ready', () => {
  console.log('Email worker started successfully');
});

emailWorker.on('error', (err) => {
  console.error('Email worker error:', err);
});
  1. 安装concurrently工具用于同时启动多个进程:
npm install concurrently --save-dev
  1. 修改package.json启动脚本:
{
  "scripts": {
    "dev": "concurrently \"next dev\" \"npm run start-worker\"",
    "start-worker": "node scripts/start-email-worker.js",
    "build": "next build",
    "start": "concurrently \"next start\" \"npm run start-worker\""
  }
}

4. 在Server Component/getServerSideProps中初始化(不推荐,依赖页面渲染)

  • Pages Router:在页面的getServerSideProps中导入Worker,用全局变量判断避免重复初始化:
// pages/index.tsx
export async function getServerSideProps() {
  if (!global.emailWorker) {
    const { emailWorker } = await import('../lib/workers/email-worker');
    global.emailWorker = emailWorker;
  }
  return { props: {} };
}
  • App Router:在根Layout Server Component中直接导入Worker文件,服务器渲染时会执行初始化:
// app/layout.tsx
import './lib/workers/email-worker';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

这种方式依赖页面或布局的访问,可靠性不如前几种方案,仅适合小型项目临时使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 11:22:35