一点背景。
非常大的单片Django应用程序。所有组件都使用相同的数据库。我们需要分离服务,以便我们可以独立升级系统的某些部分而不影响其余部分。
我们使用RabbitMQ作为Celery的经纪人。
现在我们有两个选择:
我的团队倾向于HTTP,因为这是他们熟悉的,但我认为使用RPC而不是AMQP的优势远远超过它。
AMQP为我们提供了轻松添加负载平衡和高可用性以及保证消息传递的功能。
对于HTTP,我们必须创建客户端HTTP包装器以使用REST接口,我们必须放入负载均衡器并设置该基础结构以便使用HA等。
使用AMQP我可以生成另一个服务实例,它将连接到与其他实例相同的队列以及bam,HA和负载平衡。
我对AMQP的想法遗漏了什么?
答案 0 :(得分:82)
首先,
pickle
,它应该比JSON或任何其他格式更快。</ li>
因此,如果您选择使用什么:HTTP + REST或AMQP + RPC,答案实际上是基础架构复杂性和资源使用的主题。没有任何特定要求,两个解决方案都可以正常工作,但我宁愿做一些抽象,以便能够透明地在它们之间切换。
您告诉您的团队熟悉HTTP但不熟悉AMQP。如果开发时间是一个重要的时间,你会得到一个答案。
如果您想以最小的复杂度构建HA基础架构,我想AMQP协议就是您想要的。
我有两种体验,RESTful服务的优点是:
基于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 vs. 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提供了一个pub / sub接口,其中HTTP是点对点的。
UPD(2018年12月): 正如@Kevin在下面的评论中所注意到的那样,RabbitMQ比RESTful服务更好地扩展是值得怀疑的。我原来的答案是基于简单地添加更多的工作人员,这只是扩展的一部分,只要单个AMQP经纪人的能力没有超过,这是事实,但在此之后它需要更先进的技术,如Highly Available (Mirrored) Queues基于HTTP和AMQP的服务在基础架构级别具有一些非平凡的复杂性。
经过深思熟虑后,我还删除了维护AMQP代理(RabbitMQ)比任何HTTP服务器都简单:原始答案是在2013年6月写的,并且自那时以来发生了很多变化,但主要的变化是我获得了更多的洞察力两种方法,所以我现在可以说最好的&#34;你的里程可能会有所不同&#34;。
另请注意,比较HTTP和AMQP在某种程度上是苹果到橙子,所以请不要将此答案解释为作出决定的最终指导,而是将其作为来源之一或作为参考您的进一步研究,以找出与您的具体案例相匹配的确切解决方案。
答案 1 :(得分:17)