繁体   English   中英

如何使用消息队列在 Node JS 中执行长事件处理?

[英]How to perform long event processing in Node JS with a message queue?

我正在使用 Google Pub/Sub 作为消息队列在 Node JS 中构建 email 处理管道。 消息队列有一个限制,它需要在 10 分钟内确认已发送的消息。 但是,它发送到 Node JS 服务器的作业可能需要一个小时才能完成。 因此,同一个作业可能会运行多次,直到其中一个完成。 我担心这会阻塞 Node JS 事件循环并降低服务器速度。

查找随附的架构图。 我的问题是:

  1. 鉴于消息队列期望在 10 分钟内得到响应,我应该使用消息队列来启动这个长时间运行的工作,还是我应该考虑其他一些架构?
  2. 如果启动多个此类作业,我是否应该担心 Node JS 事件循环被阻塞。 每个作业基本上都是通过 MongoDB cursor 迭代创建数十万封电子邮件。

架构图

好吧,听起来您要么不应该使用该队列(超时无法更改),要么您应该将工作分解为在超时之前很长时间很容易完成的工作。 听起来您只需要将工具与工作要求相匹配。 如果该队列不符合您的要求,您可能需要不同的机制。 我不完全了解您从 Google 的 pub/sub 中需要什么,但是如果您只想序列化对一堆作业的访问,那么创建自己的队列或在 NPM 上找到通用队列通常相当容易。

只要您的所有 I/O 都使用异步方法,我宁愿怀疑您是否存在 nodejs 事件循环阻塞问题。 您所做的一切听起来都占用大量 CPU,这就是阻塞事件循环(长时间运行占用大量 CPU 的操作)的原因。 您的整个项目可能受到 MongoDB 和您用来发送电子邮件的任何东西的限制,因此您可能应该确保您没有压倒其中任何一个,以至于它们变得迟缓并失去吞吐量。

要回答原始问题:

  1. 鉴于消息队列期望在 10 分钟内得到响应,我应该使用消息队列来启动这个长时间运行的工作,还是我应该考虑其他一些架构?

是的,消息队列非常适合处理这些类型的事件。 重要的是要确保最终的动作是幂等的,这样即使你不小心处理了重复的事件,最终的结果也会被应用一次。 来自 Google Cloud 的这份指南是使您的订阅者具有幂等性的有用资源。

为了绕过 Pub/Sub 的 10 分钟限制,我最终创建了一个内存表来跟踪活动作业。 如果正在积极处理作业并且 Pub/Sub 再次发送消息,它将什么都不做。 如果服务器重新启动并丢失作业,内存中的表也会消失,因此如果作业不完整,可以再次处理。

  1. 如果启动多个此类作业,我是否应该担心 Node JS 事件循环被阻塞。 每个作业基本上都是通过 MongoDB cursor 迭代创建数十万封电子邮件。 根据 jfriend00 留下的评论,我暂时忽略了这一点。 您还可以对正在处理的作业数量进行速率限制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM