NestJS 队列

195 阅读2分钟

队列是一种有用的设计模式,可以帮助你处理一般应用规模和性能的挑战。一些队列可以帮助你处理的问题示例包括:平滑输出峰值、将可能阻塞Node.js事件循环的整体任务打碎、在不同的服务间提供一个可信的通讯通道。

Bull 使用Redis持久化工作数据,因此你需要在你的系统中安装 Redis。

//参考:https://cloud.tencent.com/developer/article/2343208

安装

$ npm install --save @nestjs/bull bull
$ npm install --save-dev @types/bull

导入

在根AppModule中导入BullModule。app.module.ts

要在对应模块中导入BullModule。不然报错。

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      redis: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}

生产者

任务生产者添加任务到队列中。生产者是典型的应用服务(Nest 提供者)。

import { Injectable } from '@nestjs/common';
import { InjectQueue } from '@nestjs/bull';
import { Queue } from 'bull';
 
@Injectable()
export class AppService {
  constructor(
    // 这里 audio 名称,是 audioConsumer 这个文件里面的消费者定义的名称
    @InjectQueue('audio') private readonly myQueue: Queue,
  ) {}
 
  async addJobToQueue() {
    console.log('进入方法');
    const job = await this.myQueue.add({
      foo: 'bar',
    });
    console.log(job);
  }
}

命名的任务

任务需要独一无二的名字。这允许你创建专用的消费者,这将仅处理给定名称的处理任务。

const job = await this.myQueue.add('transcode', {
  foo: 'bar',
});

消费者

消费者是一个类,定义的方法要么处理添加到队列中的任务,要么监听队列的事件,或者两者皆有。使用@Processor()装饰器来定义消费者类。装饰器的字符串参数(例如,audio)是和类方法关联的队列名称。

// audio/audioConsumer.ts
// app.module.ts 中导入 providers: [AudioConsumer]
import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {
  @Process()
  transcode(job: Job<unknown>) {
    console.log('队列处理',job);
    return {};
  }
}

调用方法

// app.controller.ts
export class AppController {
  constructor(private readonly appService: AppService){}

  @Get()
  QetHello(){
    this.appService.addJobToQueue();
  }
}

一个消费者有多个方法

export class AudioConsumer {

  @Process('xfz1')
  async xfz1(job:Job){
    console.log('xfz1 处理');
    console.log(job);
    return {};
  }

  @Process('xfz2')
  async xfz2(job:Job){
    console.log('xfz2 处理');
    console.log(job);
    return {};
  }
}

  async addJobToQueue() {
    // 指定 audio 消费者里面的 xfz1 方法处理
    await this.myQueue.add('xfz1',{
      foo: 'bar',
    });
    // 指定 audio 消费者里面的 xfz2 方法处理
    await this.myQueue.add('xfz2',{
      foo: 'bar',
    });
  }