消息队列与Web服务?[关闭]


258

在什么条件下,人们会偏爱通过消息队列而不是通过Web服务进行交谈的应用程序(我只是说XML,JSON或YAML或此处通过HTTP进行的任何操作,而不是任何特定类型)?

我必须在局域网上的两个应用程序之间进行交谈。一个将是Web应用程序,并且必须在另一个应用程序(在不同的硬件上运行)上请求命令。这些请求包括创建用户,移动文件和创建目录之类的事情。在什么情况下,与使用消息队列相比,我更喜欢XML Web服务(或直接TCP或其他)?

Web应用程序是Ruby on Rails,但我认为问题比这更广泛。

Answers:


315

使用Web服务时,您有一个客户端和一个服务器:

  1. 如果服务器发生故障,客户端必须负责处理错误。
  2. 当服务器再次工作时,客户端负责重新发送它。
  3. 如果服务器对呼叫做出响应,而客户端失败,则操作将丢失。
  4. 您没有争执,那就是:如果数百万的客户在一秒钟内在一台服务器上调用了Web服务,则很可能您的服务器将关闭。
  5. 您可以期望服务器立即做出响应,但是您也可以处理异步调用。

当您使用RabbitMQ,Beanstalkd,ActiveMQ,IBM MQ系列,Tuxedo之类的消息队列时,您会期望得到不同且容错性更高的结果:

  1. 如果服务器出现故障,队列将保留该消息(可选,即使计算机关闭)。
  2. 当服务器再次工作时,它将收到挂起的消息。
  3. 如果服务器对呼叫做出响应并且客户端失败,则如果客户端未确认响应,则消息将保留。
  4. 您有争用,可以决定服务器处理多少个请求(取而代之的是工作程序)。
  5. 您不希望立即得到同步响应,但是您可以实现/模拟同步调用。

Message Queues具有更多功能,但这是决定是否要自己处理错误条件或将其留在消息队列中的一些经验法则。


1
如果使用SOAP / JMS绑定,则在Web服务上也会获得松散的耦合。
koppor

对于服务器端的多个微服务,应该首选哪个Web服务或队列?
shivendra pratap singh

亲爱的@sw。,我是否知道这是否意味着我们可以将MQ置于普通网站的前面?假设我有Wordpress网站(LAMP堆栈)。我可以使用Apache的MQ infront来使请求在1到1之后发出,而不是在同一时间发出。在这种情况下,客户端(浏览器)连接到MQ而不是Apache,是吗?但是,浏览器是否保持HTTP连接打开并一直等待Apache响应?请帮助我对此有所了解。感谢您的好意。
夏期剧场

@夏期剧场您的用例是什么?您想通过什么方式使使用浏览器的最终用户受益?
sw。

这些与客户端/服务器设置有关的问题还不是在队列与服务器之间以及在客户端与队列之间吗?似乎客户机/服务器范例仍然存在,现在在两个地方。
–imaginerThat

75

在考虑REST HTTP调用如何替代消息队列概念方面,最近有大量研究。

如果您将流程和任务的概念作为资源进行介绍,则对中间消息层的需求开始消失。

例如:

POST /task/name
    - Returns a 202 accepted status immediately
    - Returns a resource url for the created task: /task/name/X
    - Returns a resource url for the started process: /process/Y

GET /process/Y
    - Returns status of ongoing process

一个任务可以有多个初始化步骤,一个进程在被轮询时可以返回状态,或者在完成时可以返回到回调URL。

这非常简单,当您意识到您现在可以订阅所有正在运行的进程和任务的rss / atom feed而没有任何中间层时,它将变得非常强大。无论如何,任何排队系统都将需要某种Web前端,并且此概念已内置,而没有另一层自定义代码。

资源将一直存在,直到您将其删除为止,这意味着您可以在流程和任务完成后很长时间查看历史信息。

您已经内置了服务发现,甚至对于具有多个步骤的任务也没有任何复杂的协议。

GET /task/name
    - returns form with required fields

POST (URL provided form's "action" attribute)

您的服务发现是HTML表单-一种通用且易于阅读的格式。

整个流程可以通过编程方式使用,也可以由人类使用通用工具来使用。它是客户端驱动的,因此是RESTful的。为网络创建的每个工具都可以推动您的业务流程。通过异步POST到单独的日志服务器阵列,您仍然具有备用消息通道。

在考虑了一会儿之后,您会坐下来开始意识到REST可能完全不需要消息队列和ESB。

http://www.infoq.com/presentations/BPM-with-REST


11
@tempire容错等等呢?REST很好,但是开发人员最终自己构建了中间件
Dan Rosenstark 2011年

10
@Yar有关“这是什么”的大多数问题都可以重申,“如何在网络上处理?”。容错可以通过负载均衡器甚至是dns记录来处理。还有其他一些问题有待解决,例如水平可伸缩性-网络本身无法很好地处理(例如ddos攻击)。
tempire 2011年

8
@tempire,网络上没有保证的交付,对吗?我点击提交并祈祷消息到达目的地。有了MQ,我知道如果我开始使用MQ,那就完成了。它将处理将消息发送到目的地。
Dan Rosenstark 2011年

10
@Yar考虑一下“保证交付”是什么意思。它仅与消息队列的正常运行时间一样“保证”。将消息队列替换为将任务和流程视为资源的REST服务器,您将获得与其他任何事物相同的“保证”。本质上,您仍然有一个消息队列,但是采用Web标准可访问格式,可以使用任何Web工具对其进行监视。
tempire 2011年

16
@Yar-我认为很多人都不会理解MQ试图解决的问题定义,甚至可以考虑这些问题。他们了解MQ,但这与了解问题空间不同。不过,这是一个普遍存在的问题,因为我认为世界上大多数程序员和经理都已经接受过连接零件而不是工程师解决方案的培训。
tempire 2011年

32

消息队列非常适合可能需要很长时间处理的请求。请求被排队,并且可以在不阻止客户端的情况下脱机处理。如果需要将完成通知客户端,则可以为客户端提供一种定期检查请求状态的方法。

消息队列还使您可以跨时间更好地扩展。因为实际的处理过程可以跨时间分布,所以它可以提高您处理大量活动的能力。

请注意,消息队列和Web服务是正交的概念,即它们不是互斥的。例如,您可以有一个基于XML的Web服务,它充当消息队列的接口。我认为您要寻找的区别是消息队列与请求/响应,后者是请求被同步处理时。


3
是的,我只是在想:这不是他们在阻止还是不阻止。这是它们是否需要更长和/或不可预测的时间来处理...关于它们的正交性,也确实可以使用Web服务来处理较长的请求(当然,分离和提取也要分开)。但是,如果您有消息队列这样的奢侈品,那可能是个好主意。
丹·罗森斯塔克

我的新问题是,如果希望流程是同步的,但在超时时异步呢?然后,也许Web服务会更合适。
丹·罗森斯塔克

27

消息队列是异步的,如果传递失败,则可以重试多次。如果请求者不需要等待响应,则使用消息队列。

短语“ Web服务”使我想到了通过HTTP对分布式组件的同步调用。如果请求者需要回复,请使用Web服务。


1
为此,是的,“保证交付”,我将不得不考虑这是否重要。我的意思是,从某种意义上说,同步与异步有点儿滋味。尽管显然有黑白情况,但中间还有一个巨大的灰色。
Dan Rosenstark 2010年

22

我认为通常来说,您需要一个用于阻塞任务的Web服务(此任务需要在执行更多代码之前完成),以及一个用于非阻塞任务的消息队列(可能需要一段时间,但我们不希望这样做)。无需等待)。


Web服务还提供单向方法(@Oneway)。为了接收答案,客户端必须提供Web服务。
koppor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.