Nestjs框架: nestjs-schedule模块中的三类定时任务

三类定时任务

  • task schedule 要做的三件事情
    • 添加定时任务
    • 删除定时任务
    • 获取所有定时任务的状态
  • 什么类型的任务适合使用 task.schedule 模块
    • 周期性任务:如每天、每小时、每周执行的任务,适合使用 taskschedule 模块
      • 每天看签到任务是否完成, 未完成则给用户添加 task queue 的消息
      • 这是周期性任务 和 task queue 配合的示例
    • 简单任务:像系统状态或接口状态的检查,可通过发起请求判断,将响应数据存储到数据库方便后续读取
    • 轻量级任务:任务不常执行且任务量不大的情况,适合使用 task schedule (非高并发任务)
  • task schedule 不适合做什么
    • 给用户发送指定日期某一分,某一秒的消息
  • 如果是大量高并发的任务,使用 task queue
    • task queue 可以实现给用户发送指定日期某一分,某一秒的消息
    • task queue 在 nestjs 中有一个 nestjs bull + redis 的方案
    • task queue 其他方案: RabbitMQ,MessageMQ, Kafka 方案

合理规划 tasks 定时任务

  • common
    • cron
      • tasks
        • log-db-cron.service.ts
        • index.ts
      • tasks.module.ts
      • tasks.service.ts

1 ) cron/tasks/log-db-cron.service.ts

import { Injectable } from '@nestis/common';
import { Cron } from '@nestjs/schedule';
import { SshService } from '@/utils/ssh/ssh.service';

@Injectable();
export class LogDbCronService {
	constructor(private sshService: sshService) {}
	
	@Cron('0 * 0 * *', {name: 'logdb-cron'})
	handleCron(){
		//备份:连接到MongoDB并导出对应的db中的collections的数据
		//滚动记录:删除已有的collections的数据
		//1.删除当前collections中的已备份数据
		//2.之前备份的collections->对比collection备份的时间,如果超过t天/hours的规则,则删除
		const containerName = 'mongo-mongo-1';
		const uri='mongodb: //root: example@localhost: 27017/nest-logs';
		const now = new Date();
		const collectionName = 'log';
		const outputPath =`/tmp/logs-${now.getTime()}`;
		const hostBackupPath = '/srv/logs';
		const cmd =`docker exec -i ${containerName} mongodump --uri=${uri} --collection=${collectionName} --out=${outputPath}`;
		const cpCmd =`docker cp ${containerName}:${outputPath} ${hostBackupPath}`;
		await this.sshService.exec(`${cmd} && ${cpCmd}`)
		await this.sshService.exec(`ls-la ${hostBackupPath}`);
		const delCmd = `find ${hostBackupPath} -type d -mtime +30 -exec rm
		-rf {}\\;`;
		await this.sshService.exec(delCmd)
		const res = await this.sshService.exec(`ls-la ${hostBackupPath}`);
		console.log('~ TasksService ~ handleCron ~ res:', res);
	}
}

2 ) cron/tasks/index.ts

import { Provider } from '@nestjs/common';
import { LogDbCronService } from './tasks/log-db-cron.service';

export const CronProviders: Provider[] = [LogDbCronService];

3 ) tasks.module.ts

$ nest g mo common/cron/tasks --no-spec --flat -d
生成 nest g mo common/cron/tasks.module.ts

import { Module } from '@nestjs/common';
import { TasksService } from './tasks.service';
import { ScheduleModule } from '@nestjs/schedule';
import { CronProviders } from './tasks/index';


@Module({
	imports: [ScheduleModule.forRoot()],
	providers: [TasksService, ...CronProviders],
	exports: [TasksService],
})

export class TasksModule {}

4 ) task.service.ts

import { Injectable, Logger } from '@nestjs/common';
import { SchedulerRegistry } from '@nestjs/schedule';
import { CronJob } from 'cron';

@Injectable()
export class TasksService {
	logger = new Logger('TasksService');
	constructor(private schedulerRegistry: SchedulerRegistry){}

	//添加定时任务
	addCronJob(name: string, cronTime: string, cb:()=> void): void {
		const job = new CronJob(cronTime, cb);
		this.schedulerRegistry.addCronJob(name, job);
		job.start();
		this.logger.log(`Job ${name} added and started`);
	}

	// 删除定时任务
	deleteCronJob(name: string): void {
		this.schedulerRegistry.deleteCronJob(name);
		this.logger.warn(`Job ${name} deleted`);
	}

	// 获取所有的定时任务的状态
	getCrons() {
		const jobs = this.schedulerRegistry.getCronJobs();
		jobs.forEach((value, key) => {
			let next;
			try {
				next = value.nextDate().toJSDate();
			} catch(e) {
				next = 'error: next fire date is in the past!';
			}
			this.logger.log(`job: ${key} -> next: ${next}`); // key 是 id, next 下一次执行任务的时间
		});
	}
}

这是控制定时任务的 添加,删除,获取所有的定时任务

5 ) 使用

  • 在某个模块,比如 auth.mdoule.ts 导入 TasksModule

    import { Module } from '@nestjs/common';
    import { TasksModule } from '@/common/cron/tasks.module';
    
    @Module({
    	imports: [
    		TasksModule,
    	]
    })
    
    export class AuthModule {}
    
  • 之后再 auth.controller.ts 导入

    import { Module, Get } from '@nestjs/common';
    import { TasksService } from '../../common/cron/tasks.service';
    
    @Controller('auth');
    export class AuthController {
    	constructor(
    		private tasksService: TasksService
    	) {}
    
    	@Get('add-job')
    	getAddJob() {
    		// 每分钟执行一次 写死的任务名称
    		this.tasksService.addCronJob('test', '*****', () => {
    			console.log('hello schedule job');
    		});
    		return 'created';
    	}
    
    	@Get('delete-job')
    	deleteJob() {
    		this.tasksService.deleteCronJob('test'); // 写死的任务名称
    		return 'deleted';
    	}
    
    	@Get('get-jobs')
    	getJobs() {
    		this.tasksService.getCrons();
    		return 'get jobs';
    	}
    }
    
  • 以上都是简单的测试,调用对应的 api 即可测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值