如何在NestJS和Bull中使用Heroku Background Workers?

14ifxucb  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(189)

对于我想使用NestJS在我的队列上运行的重进程,推荐的方法是什么?
我有一个在Heroku上运行的HTTP服务器,它执行某些耗时的任务(例如:例如,与某些第三方API通信),我希望放在队列中并委托给后台工作者。
阅读this example,似乎我会创建一个处理器文件,并在那里示例化Queue对象,然后定义它的process函数。这似乎允许放大,因为每个进程都有Queue对象,并在其中定义它的process。生产更多的dynos将提供更多的工人。
看这里,我看到我可以在注册队列时声明进程文件。在这里我不需要示例化Queue对象并将其定义为process,我可以简单地将export定义为default function。我是否可以在我的Procfile中声明一个指向这些进程文件的辅助进程,并扩展它们?这样行吗还是我漏掉了什么
现在,我没有设置单独的进程。我在Nest的IoC容器中使用给定的装饰器定义了ProcessorsProcesses。我以为事情会很顺利。我所看到的是,作业来得很快,我的服务器无法跟上所有的请求和作业。

zbsbpyhn

zbsbpyhn1#

几个月后,我将为未来的读者回答我自己的问题。
解决这个问题的关键是我理解队列的一般模式。队列一般由3部分组成:
1.实际的Queue驻留在某个地方的数据存储中(本地内存,Redis等)。)
1.生产者(将作业添加到队列)
1.消费者(处理队列上的作业)
所有3个部分都可以存在于同一个脚本中,例如,通过将作业保存到本地内存中的Queue数据结构中并逐个处理它们。
通常情况下,我们希望通过本地内存的不稳定性来持久化我们的作业,所以我们将使用像Redis这样的Memcache服务来保存我们的Queue。
生产者(Queue.add(job))和消费者(Queue.process(function))可以存在于同一脚本中。这就是NestJS文档所演示的。Producer和Consumer都由同一个进程执行,即在main.ts中启动的NestJS应用程序。然而,它们可以从对方那里窃取资源,在Web环境中,服务器在任何时候都可以响应传入的请求是非常重要的。不仅如此,这些工作可能会被大量涌入的请求挤到一边。
因此,我们可以将(Queue.process(function))代码移动到不同的脚本中,并从不同的shell(进程)运行它。从本质上讲,这就是Heroku背景工作者。它们是在不同shell中运行的进程,因此不会相互干扰。
明白了这一点,接下来就简单了。

加入队列

添加到队列是在NestJS应用程序中根据传入的请求完成的。

@Injectable()
export class SomeService {
  constructor(@InjectQueue('my_queue') private readonly myQueue: Queue) {}

  addToQueue(jobData: JobData) {
    await this.myQueue.add(jobData);
    
    return 'Added to Queue';
  }
}

处理队列中的作业

在一个单独的脚本中,比如my-queue.process.ts

import Queue from 'bull';

const myQueue = new Queue('my_queue', process.env.REDIS_URL);

myQueue.process(async (job: JobData) => {
  await somePromise(job.data.id);
  return 'success';
});

这里唯一需要注意的是,NestJS应用程序中定义的任何服务都不能通过注入获得,因此我们需要自己示例化它们并提供必要的注入。例如:

const myService = new SomeService();
// myOtherService depends on myService. In Nest, it was automatically injected in the constructor. 
const myOtherService = new SomeOtherService(myService);

这会很麻烦的我的脚本在到达消费者之前有很多这样的内容。但是它可以工作,我还没有找到一种干净的方法来用一行程序注入所有的模块依赖项。
这就是我们的工人。
在我们的Procfile中,我们会有一行看起来像这样:
worker: node dist/path/to/my-queue.process.ts
这是理解如何编排这个流程的基础。
查看以下关于Heroku的文章,深入了解您可以使用Heroku后台工作人员做些什么:Heroku Article
从他们的示例代码中可以获得更多的见解:Github repo( checkout worker.js

相关问题