队列是一种有用的设计模式,可以帮助你处理一般应用规模和性能的挑战。一些队列可以帮助你处理的问题示例包括:平滑输出峰值、将可能阻塞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',
});
}