64

一点背景。

非常大的单体 Django 应用程序。所有组件都使用相同的数据库。我们需要分离服务,以便我们可以独立升级系统的某些部分而不影响其余部分。

我们使用 RabbitMQ 作为 Celery 的代理。

现在我们有两个选择:

  1. 使用 REST 接口的 HTTP 服务。
  2. JSONRPC over AMQP 到事件循环服务

我的团队倾向于 HTTP,因为这是他们所熟悉的,但我认为使用 RPC 而不是 AMQP 的优势远远超过它。

AMQP 为我们提供了轻松添加负载平衡和高可用性的功能,并保证消息传递。

而对于 HTTP,我们必须创建客户端 HTTP 包装器以使用 REST 接口,我们必须放入负载均衡器并设置该基础架构以拥有 HA 等。

使用 AMQP,我可以生成另一个服务实例,它将连接到与其他实例和 bam、HA 和负载平衡相同的队列。

我对 AMQP 的想法是否遗漏了什么?

4

2 回答 2

103

首先,

  • REST、RPC - 架构模式、AMQP - 线路级和 HTTP - 在 TCP/IP 之上运行的应用程序协议
  • AMQP 是 HTTP 时的特定协议 - 通用协议,因此,与 AMQP 相比,HTTP 具有非常高的开销
  • AMQP 本质是异步的,而 HTTP 本质是同步的
  • REST 和 RPC 都使用数据序列化,哪种格式取决于您并且取决于基础设施。如果你在任何地方都使用 python,我认为你可以使用 python 原生序列化——pickle它应该比 JSON 或任何其他格式更快。
  • HTTP+REST 和 AMQP+RPC 都可以在异构和/或分布式环境中运行

因此,如果您选择使用什么:HTTP+REST 或 AMQP+RPC,答案实际上取决于基础架构复杂性和资源使用情况。没有任何特定要求,两种解决方案都可以正常工作,但我宁愿做一些抽象,以便能够透明地在它们之间切换。

您告诉您的团队熟悉 HTTP 但不熟悉 AMQP。如果开发时间是一个重要的时间,你就会得到答案。

如果你想以最小的复杂性构建 HA 基础设施,我猜 AMQP 协议就是你想要的。

我对它们都有过经验,RESTful 服务的优点是:

  • 他们在网络界面上很好地映射
  • 人们熟悉它们
  • 易于调试(由于 HTTP 的通用性)
  • 轻松向第三方服务提供API。

基于 AMQP 的解决方案的优势:

  • 该死的快
  • 灵活的
  • 成本效益(在资源使用意义上)

请注意,您可以在基于 AMQP 的 API 之上向第三方服务提供 RESTful API,而 REST 不是协议而是范例,但您应该考虑使用它来构建您的 AQMP RPC api。我这样做是为了向外部第三方服务提供 API,并提供对在旧代码库上运行或无法添加 AMQP 支持的基础架构部分的 API 访问。

如果我是对的,您的问题是关于如何更好地组织软件不同部分之间的通信,而不是如何为最终用户提供 API。

如果您有一个高负载项目,RabbitMQ 是一款非常棒的软件,您可以轻松添加任意数量的在不同机器上运行的工作程序。它还具有开箱即用的镜像和集群功能。还有一件事,RabbitMQ 是建立在 Erlang OTP 之上的,这是一个高可靠、稳定的平台……(bla-bla-bla),它不仅对营销有好处,对工程师也有好处。当 nginx 日志占用运行 RabbitMQ 的同一分区上的所有磁盘空间时,我只遇到过一次 RabbitMQ 问题。

UPD(2018 年 5 月): Saurabh Bhoomkar在 2012 年 6 月 7 日发布了 Arnold Shoon 所写的MQ 与 HTTP文章的链接,这是它的副本:

我正在浏览我的旧文件并看到我关于 MQ 的笔记,并认为我会分享一些使用 MQ 与 HTTP 的理由:

  • 如果您的消费者以固定速率处理(即无法处理对 HTTP 服务器的洪水 [bursts]),那么使用 MQ 为服务提供了缓冲其他请求而不是使其陷入困境的灵活性。
  • 与时间无关的处理和消息交换模式——如果线程正在执行即发即弃,那么 MQ 比 HTTP 更适合该模式。
  • 长寿命进程更适合 MQ,因为您可以发送请求并拥有一个单独的线程来监听响应(注意 WS-Addressing 允许 HTTP 以这种方式处理,但需要两个端点都支持该功能)。
  • 松散耦合,即使另一个进程不可用,一个进程也可以继续工作,而 HTTP 必须重试。
  • 请求优先级,更重要的消息可以跳到队列的前面。
  • XA 事务——MQ 完全符合 XA——HTTP 不是。
  • 容错 – MQ 消息在服务器或网络故障中仍然存在 – HTTP 不能。
  • MQ 提供了一次且仅一次的“可靠”消息传递,http 没有。
  • MQ 提供了对大型消息进行消息分段和消息分组的能力——HTTP 没有这种能力,因为它单独处理每个事务。
  • MQ 提供了一个发布/订阅接口,其中 HTTP 是点对点的。

UPD(2018 年 12 月):正如@Kevin在下面的评论中所注意到的,RabbitMQ 的扩展性比 RESTful 服务更好是值得怀疑的。我最初的答案是基于简单地添加更多工作人员,这只是扩展的一部分,只要不超过单个 AMQP 代理容量,这是真的,尽管之后它需要更高级的技术,如高可用(镜像)队列,这使得基于 HTTP 和 AMQP 的服务都具有一些在基础设施级别扩展的不平凡的复杂性。

经过仔细考虑,我还删除了维护 AMQP 代理(RabbitMQ)比任何 HTTP 服务器都简单:原始答案写于 2013 年 6 月,自那时以来发生了很多变化,但主要变化是我对这两种方法都有更多的了解,所以我现在能说的最好的就是“你的里程可能会有所不同”。

另请注意,在某种程度上比较 HTTP 和 AMQP 是苹果与橘子,所以请不要将此答案解释为您做出决定的最终指导,而是将其作为来源之一或作为您进一步研究的参考找出与您的特定情况相匹配的确切解决方案。

于 2013-06-25T12:05:54.397 回答
20

OP 不得不接受的解决方案具有讽刺意味的是,AMQP 或其他 MQ 解决方案通常用于将调用者与纯 HTTP 服务的固有不可靠性隔离开来——提供某种程度的超时和重试逻辑以及消息持久性,因此调用者不会不必实现自己的 HTTP 隔离代码。在可靠的 AMQP 核心之上的非常薄的 HTTP 网关或适配器层,可以选择使用更可靠的客户端协议(如 JSONRPC)直接进入 AMQP,这通常是这种场景的最佳解决方案。

于 2013-08-27T11:03:35.017 回答