Nestjs项目实战 任务调度与定时任务实现
在Nestjs项目中实现任务调度和定时任务时,遇到了几个问题想请教大家:
- 如何正确使用@nestjs/schedule模块配置定时任务?我的任务有时无法按预期时间触发
- 动态创建/取消定时任务的推荐做法是什么?目前尝试用SchedulerRegistry修改cron表达式但不起作用
- 集群环境下部署时,定时任务会被多个实例重复执行,有什么解决方案?
- 长时间运行的定时任务阻塞主线程,是否应该改用Queue或单独微服务处理?
- 有没有成熟的错误处理机制?现在任务报错会导致整个应用崩溃
3 回复
在NestJS中实现任务调度和定时任务,可以使用node-schedule
或cron
模块。以下是基本步骤:
-
安装依赖:
npm install node-schedule
-
创建任务服务: 创建一个服务来管理定时任务,例如
tasks.service.ts
。import { Injectable } from '[@nestjs](/user/nestjs)/common'; import schedule from 'node-schedule'; [@Injectable](/user/Injectable)() export class TasksService { startTask() { schedule.scheduleJob('*/5 * * * *', () => { console.log('每5分钟执行一次'); }); } }
-
在模块中注入服务: 在
app.module.ts
中引入并注入该服务。import { Module } from '[@nestjs](/user/nestjs)/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { TasksService } from './tasks/tasks.service'; [@Module](/user/Module)({ imports: [], controllers: [AppController], providers: [AppService, TasksService], }) export class AppModule {}
-
启动任务: 在
main.ts
中调用任务服务的方法。async function bootstrap() { const app = await NestFactory.create(AppModule); const tasksService = app.get(TasksService); tasksService.startTask(); await app.listen(3000); } bootstrap();
这样就实现了简单的定时任务调度。可根据需求调整调度规则。
在NestJS中实现任务调度和定时任务,可以使用@nestjs/schedule
模块。首先安装依赖:
npm install @nestjs/schedule --save
然后启用定时任务模块,在app.module.ts
里配置:
import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
@Module({
imports: [
ScheduleModule.forRoot(),
],
})
export class AppModule {}
接着创建一个定时任务服务,比如task.service.ts
:
import { Injectable } from '@nestjs/common';
import { SchedulerRegistry } from '@nestjs/schedule';
@Injectable()
export class TaskService {
constructor(private schedulerRegistry: SchedulerRegistry) {}
addCronJob(name: string, cronTime: string, callback: Function) {
const job = new CronJob(cronTime, callback);
this.schedulerRegistry.addCronJob(name, job);
job.start();
}
stopCronJob(name: string) {
const job = this.schedulerRegistry.getCronJob(name);
if (job) {
job.stop();
this.schedulerRegistry.deleteCronJob(name);
}
}
}
通过注入TaskService
即可灵活地添加或停止定时任务,比如每5秒执行一次任务:
this.taskService.addCronJob('testJob', '* * * * *', () => console.log('任务执行'));
记得处理好任务异常,避免程序崩溃。
NestJS 任务调度与定时任务实现
在NestJS中实现任务调度和定时任务主要有以下几种方式:
1. 使用@nestjs/schedule模块
这是NestJS官方提供的定时任务解决方案,基于node-cron和node-schedule。
安装依赖
npm install --save [@nestjs](/user/nestjs)/schedule
基本使用
import { Module } from '[@nestjs](/user/nestjs)/common';
import { ScheduleModule } from '[@nestjs](/user/nestjs)/schedule';
@Module({
imports: [
ScheduleModule.forRoot()
],
})
export class AppModule {}
三种类型的定时任务
- Cron表达式任务
import { Injectable, Logger } from '[@nestjs](/user/nestjs)/common';
import { Cron } from '[@nestjs](/user/nestjs)/schedule';
@Injectable()
export class TasksService {
private readonly logger = new Logger(TasksService.name);
@Cron('45 * * * * *') // 每分钟的第45秒执行
handleCron() {
this.logger.debug('每分钟第45秒执行的定时任务');
}
}
- 间隔任务
import { Injectable, Logger } from '[@nestjs](/user/nestjs)/common';
import { Interval } from '[@nestjs](/user/nestjs)/schedule';
@Injectable()
export class TasksService {
private readonly logger = new Logger(TasksService.name);
@Interval(10000) // 每10秒执行一次
handleInterval() {
this.logger.debug('每10秒执行的定时任务');
}
}
- 超时任务
import { Injectable, Logger } from '[@nestjs](/user/nestjs)/common';
import { Timeout } from '[@nestjs](/user/nestjs)/schedule';
@Injectable()
export class TasksService {
private readonly logger = new Logger(TasksService.name);
@Timeout(5000) // 应用启动5秒后执行一次
handleTimeout() {
this.logger.debug('应用启动5秒后执行的定时任务');
}
}
2. 使用动态API
import { Injectable } from '[@nestjs](/user/nestjs)/common';
import { SchedulerRegistry } from '[@nestjs](/user/nestjs)/schedule';
@Injectable()
export class TasksService {
constructor(private schedulerRegistry: SchedulerRegistry) {}
addCronJob(name: string, seconds: string) {
const job = new CronJob(`${seconds} * * * * *`, () => {
console.log(`时间 ${seconds} 秒时执行的任务`);
});
this.schedulerRegistry.addCronJob(name, job);
job.start();
}
deleteCronJob(name: string) {
this.schedulerRegistry.deleteCronJob(name);
}
}
3. 使用分布式任务调度(如Bull)
对于需要分布式和持久化的复杂任务调度,可以使用Bull模块:
import { Module } from '[@nestjs](/user/nestjs)/common';
import { BullModule } from '[@nestjs](/user/nestjs)/bull';
@Module({
imports: [
BullModule.forRoot({
redis: {
host: 'localhost',
port: 6379,
},
}),
BullModule.registerQueue({
name: 'scheduledTasks',
}),
],
})
export class AppModule {}
以上是NestJS中实现定时任务的主要方式,根据项目需求选择合适的方法即可。