【问题标题】:Queue vs Non Blocking I/O队列与非阻塞 I/O
【发布时间】:2016-09-16 01:53:28
【问题描述】:

因此,我们正在设计一个新的微服务架构。最大的挑战之一是内部沟通。对于需要响应的通信,我们使用的是 REST API。但是对于只是想传递信息的服务来说,这种 API 处理是不必要的开销。

一种方法是使用队列。 service1 会将信息推送到队列中,service2 可以从那里消费。因此 service1 不必等待(与 API 调用不同)。 (如果在处理信息时出现任何错误,service2 可以通过回调 URL 到 service1 或任何其他方式通知;这不是问题[1])

现在有了Queue,有两种选择,一种是RabbitMQ。另一个是AWS SQS。使用 RabbitMQ,我不得不担心服务器设置和所有事情(可以完成,但想避免它)。因此,在 SQS 的 POC 之后,这似乎是一个不错的选择,但问题是 SQS 在内部使用 Rest API 与 AWS 服务器通信,在这两个点(推送时 service1,消费时 service2),都会有开销。所以现在我在想为什么不在 NodeJS 中这样做,service1 会向 service2 提供信息。 Service2 将立即响应,确认它已收到信息,如果有任何错误则 [1]。

现在我可以总结的优点/缺点是 -

RabbitMQ

  • 易于实施
  • 在接收方不可用的情况下,发送方不必担心重试。
  • 服务器设置成本 + 维护(+ 调整)

SQS

  • 最容易实施
  • 定价
  • 不断轮询消息
  • 推送/接收开销

非阻塞 API

  • 通信不需要第三种媒介
  • Service1 必须管理重试机制
  • 相对于 SQS,开销更少
  • 信息将保留在内存中,直到处理完毕

所以对某些人来说,我的问题是,使用非阻塞 API 是个好主意吗?或者在使系统可扩展方面,哪种方法更好。

编辑 - 可以使用 PubNub 或 Pusher 等 PubSub 提供程序来代替 Queue 吗?

【问题讨论】:

  • 问题中有一些有缺陷的前提。从技术上讲,SQS API 不是 REST API,如果是,我看不出它是如何令人反感的。如果 SQS 意味着轮询不是“恒定的”,那么长轮询机制就不会像自旋锁那样使用它。不完全确定在这个问题的上下文中“非阻塞 API”实际上意味着什么,因为队列的目的是在组件之间创建一个弹性缓冲区。这几乎似乎可以称为“基于意见”。
  • SQS 发出一个 HTTP 请求,这就是我的意思。非阻塞 API 是指节点应用程序将立即发送响应,确认它已收到请求,然后处理信息。
  • 如果您的应用程序发送响应然后继续处理请求,如果您不将正在处理的请求存储在某处,以便在发生故障时不会丢失,您将遇到问题崩溃、错误、过载或其他任何问题。
  • @AshwaniAgarwal,生产者和消费者是否在您的基础架构内的 Intranet 中运行?如果您想使用 SQS 并且所有其他组件都在您的数据中心中,您可能需要咨询您的 OP 团队。

标签: node.js architecture queue rabbitmq amazon-sqs


【解决方案1】:

SQS 使用 XML over http,RabbitMQ 使用AMQP,所有协议都有开销。序列化/反序列化是有代价的。亚马逊 SQS 和 AMQP 都非常高效。我会从您的计算中排除这些“开销”,而是专注于您的其他需求。

使用队列的一大优势是处理激增的活动。如果您获得 10 万次点击,并且需要发送 10 万条消息,并且您尝试将其实现为服务间调用(非阻塞或其他方式),您将遇到系统可扩展性的真正限制(如果没有,则从端口计数别的)。如果您将 100K 消息放在一个队列中,则这些消息基本上可以在远程服务器的“闲暇时间”进行处理。

此外,正如您在上面提到的,队列具有持久性,而您自己实现起来要困难得多。如果你的数据不是很重要,这不是一个大问题,但如果这些数据更重要,你真的想要一些推送到持久存储的东西(比如 SQS,或 Rabbit 持久队列)......

【讨论】:

  • 这个答案解决的问题比我用两倍多的单词所能做的更彻底。奇怪的是,它基本上完全没有文档记录,但 SQS 还可以通过将 Accept:Content-Type: 标头都设置为 application/json 来完全以 JSON 而不是 XML 进行所有 API 交互。这使得 SQS 更容易在自己滚动的环境中使用(我更喜欢)。
【解决方案2】:

我来晚了,但我已经开始使用非阻塞 I/O 并看到 NIO 的巨大好处,尤其是当您调用无法访问消息队列的外部服务时。使用固定的连接池将确保 100K 的问题以非阻塞 I/O 处理,并且不会创建过多的连接。

在调用内部服务时,首选消息队列,但假设您没有该选项,您可以利用 NIO 与重试机制和连接池来为您提供与消息队列相同的可伸缩性。这是假设接收者能够处理 NIO 调用的负载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 2018-04-06
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多