当前位置: 首页 > news >正文

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 下一次执行任务的时间});}
}

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

  • 更多参考官网
    • task-scheduling

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 即可测试

相关文章:

  • 同样是synthesis(综合) HLS和Vivado里面是有什么区别
  • 商品中心—15.库存分桶扣减的技术文档
  • Hyperledger Fabric 入门笔记(二十)Fabric V2.5 测试网络进阶之Tape性能测试
  • 3.Stable Diffusion WebUI本地部署和实践
  • 论分布式设计
  • 基于Redis分布式的限流
  • springboot整合微信App支付以及支付宝App支付
  • opensuse安装rabbitmq
  • 使用 Azure 创建虚拟机所涉及的各项资源和设置
  • 探秘 VR 逃生救援技术的奇妙世界​
  • 鸿蒙HarmonyOS 5小游戏实践:记忆翻牌(附:源代码)
  • docker stats和/proc/pid/status内存统计的差异问题
  • 生成式人工智能实战 | WGAN(Wasserstein Generative Adversarial Network, GAN)
  • GO 语言学习 之 变量和常量
  • 【git学习】学习目标及课程安排
  • React Native 如何实现拉起App
  • Spring Boot 3.2.11 Swagger版本推荐
  • js防止重复提交的3种解决方案
  • 小程序学习笔记:自定义组件创建、引用、应用场景及与页面的区别
  • AI辅助编写前端VUE应用流程