对于我想使用NestJS在我的队列上运行的重进程,推荐的方法是什么?
我有一个在Heroku上运行的HTTP服务器,它执行某些耗时的任务(例如:例如,与某些第三方API通信),我希望放在队列中并委托给后台工作者。
阅读this example,似乎我会创建一个处理器文件,并在那里示例化Queue
对象,然后定义它的process
函数。这似乎允许放大,因为每个进程都有Queue
对象,并在其中定义它的process
。生产更多的dynos将提供更多的工人。
看这里,我看到我可以在注册队列时声明进程文件。在这里我不需要示例化Queue
对象并将其定义为process
,我可以简单地将export
定义为default function
。我是否可以在我的Procfile
中声明一个指向这些进程文件的辅助进程,并扩展它们?这样行吗还是我漏掉了什么
现在,我没有设置单独的进程。我在Nest的IoC容器中使用给定的装饰器定义了Processors
和Processes
。我以为事情会很顺利。我所看到的是,作业来得很快,我的服务器无法跟上所有的请求和作业。
1条答案
按热度按时间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应用程序中根据传入的请求完成的。
处理队列中的作业
在一个单独的脚本中,比如
my-queue.process.ts
:这里唯一需要注意的是,NestJS应用程序中定义的任何服务都不能通过注入获得,因此我们需要自己示例化它们并提供必要的注入。例如:
这会很麻烦的我的脚本在到达消费者之前有很多这样的内容。但是它可以工作,我还没有找到一种干净的方法来用一行程序注入所有的模块依赖项。
这就是我们的工人。
在我们的
Procfile
中,我们会有一行看起来像这样:worker: node dist/path/to/my-queue.process.ts
这是理解如何编排这个流程的基础。
查看以下关于Heroku的文章,深入了解您可以使用Heroku后台工作人员做些什么:Heroku Article
从他们的示例代码中可以获得更多的见解:Github repo( checkout
worker.js
)