NestJS集群模式配置
在NestJS中配置集群模式时遇到几个问题:
- 官方文档提到可以使用
cluster
模块,但具体如何与NestJS应用集成?是否需要手动修改main.ts
启动逻辑? - 在多线程模式下,如何确保共享资源(如数据库连接、全局缓存)的线程安全?是否有推荐的最佳实践?
- 使用PM2等工具管理集群时,与NestJS内置的集群模式是否存在冲突?哪种方案更适合生产环境?
- 日志和监控在多实例环境下如何统一收集?是否需要额外配置?
- 遇到工作进程崩溃时,主进程是否会自动重启子进程?如何自定义异常处理流程?
3 回复
在NestJS中实现集群模式,可以利用Node.js的cluster
模块。以下是一个简单的配置步骤:
-
安装依赖:确保你的项目中有
@nestjs/core
和@nestjs/common
等必要依赖。 -
创建主进程文件(如
main-cluster.ts
):import { NestFactory } from '@nestjs/core'; import { App } from './app/app.module'; if (require.main === module) { const numCPUs = require('os').cpus().length; const workers = []; function forkWorker() { const worker = cluster.fork(); workers.push(worker); } require('events').EventEmitter.defaultMaxListeners = numCPUs; for (let i = 0; i < numCPUs; i++) { forkWorker(); } cluster.on('exit', (worker, code, signal) => { console.log(`Worker ${worker.process.pid} died`); forkWorker(); }); }
-
修改启动脚本:在
package.json
的scripts
中,添加一个启动命令来运行主进程:"start:cluster": "ts-node ./src/main-cluster.ts"
-
运行应用:使用
npm run start:cluster
启动应用,它会根据CPU核心数自动创建多个工作进程。
注意,集群模式主要用于处理高并发请求,需确保应用状态不依赖于内存共享。如果需要共享数据,可考虑使用Redis等中间件。
在NestJS中实现集群模式,可以利用Node.js的cluster
模块。以下是一个简单的配置示例:
- 首先确保你的应用是无状态的,因为集群模式下每个工作进程共享同一个端口。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const port = 3000;
// 集群模式启动
if (require.main === module) {
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`主进程 ${process.pid} 正在运行`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`工作进程 ${worker.process.pid} 已退出`);
cluster.fork();
});
} else {
await app.listen(port);
console.log(`工作进程 ${process.pid} 启动成功`);
}
}
}
bootstrap();
- 运行时直接执行该文件即可启动集群模式。
注意:集群模式适用于高并发场景,开发环境不建议使用。同时需要确保数据库连接等资源是可共享或独立的。
NestJS 集群模式配置
NestJS 可以通过集群模式充分利用多核 CPU 的性能。以下是配置 NestJS 集群模式的几种方法:
1. 使用 Node.js 原生 cluster 模块
import * as cluster from 'cluster';
import * as os from 'os';
import { NestFactory } from '[@nestjs](/user/nestjs)/core';
import { AppModule } from './app.module';
async function bootstrap() {
if (cluster.isMaster) {
const numCPUs = os.cpus().length;
console.log(`Master ${process.pid} is running`);
// Fork workers
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker) => {
console.log(`Worker ${worker.process.pid} died`);
cluster.fork();
});
} else {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
console.log(`Worker ${process.pid} started`);
}
}
bootstrap();
2. 使用 PM2 进程管理器
// ecosystem.config.js
module.exports = {
apps: [
{
name: 'my-nest-app',
script: 'dist/main.js',
instances: 'max', // 或指定数量
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
},
},
],
};
启动命令:pm2 start ecosystem.config.js
3. 使用 @nestjs/throttler 进行限流
在集群模式下,需要共享限流状态:
// app.module.ts
import { ThrottlerModule } from '[@nestjs](/user/nestjs)/throttler';
import { ThrottlerStorageRedisService } from 'nestjs-throttler-storage-redis';
@Module({
imports: [
ThrottlerModule.forRoot({
ttl: 60,
limit: 10,
storage: new ThrottlerStorageRedisService({
host: 'localhost',
port: 6379,
}),
}),
],
})
export class AppModule {}
注意事项
- 共享状态需要使用 Redis 或其他数据库
- 会话需要使用共享存储
- 确保所有实例都能访问相同的资源
- 日志需要集中管理
以上方法可以帮助您在 NestJS 中实现高效的集群模式部署。