在什么情况下,应用程序会通过消息队列而不是通过web服务(这里我指的是XML、JSON、YAML或HTTP上的任何东西,而不是任何特定类型)进行通信?

我必须在本地网络上的两个应用程序之间通话。一种是web应用,必须向另一种应用(在不同硬件上运行)请求命令。这些请求包括创建用户、移动文件和创建目录。在什么情况下,我更喜欢XML Web服务(或直接TCP或其他)而不是使用消息队列?

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


当前回答

当你使用web服务时,你有一个客户端和一个服务器:

如果服务器出现故障,客户端必须负责处理错误。 当服务器重新工作时,客户端负责重新发送服务器。 如果服务器对调用做出响应,而客户端失败,则操作将丢失。 你不会有争用,也就是说:如果一秒钟内有数百万个客户端在一台服务器上调用web服务,那么你的服务器很可能会瘫痪。 您可以期望服务器立即响应,但也可以处理异步调用。

当你使用像RabbitMQ, Beanstalkd, ActiveMQ, IBM MQ Series, Tuxedo这样的消息队列时,你会期望不同的和更容错的结果:

If the server fails, the queue persist the message (optionally, even if the machine shutdown). When the server is working again, it receives the pending message. If the server gives a response to the call and the client fails, if the client didn't acknowledge the response the message is persisted. You have contention, you can decide how many requests are handled by the server (call it worker instead). You don't expect an immediate synchronous response, but you can implement/simulate synchronous calls.

消息队列有更多的特性,但这是一些经验法则,可以决定您是希望自己处理错误条件,还是将其留给消息队列。

其他回答

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

“web服务”这个短语让我想到了通过HTTP对分布式组件的同步调用。如果请求者需要返回响应,则使用web服务。

我认为,通常情况下,您需要为阻塞任务提供web服务(在执行更多代码之前需要完成这些任务),为非阻塞任务提供消息队列(可能需要相当长的时间,但我们不需要等待它)。

消息队列是处理时间较长的请求的理想选择。请求是排队的,可以脱机处理而不会阻塞客户端。如果需要通知客户端完成,可以提供一种方法让客户端定期检查请求的状态。

消息队列还允许您更好地跨时间扩展。它提高了你处理大量活动的能力,因为实际的处理可以在不同的时间分布。

注意消息队列和web服务是正交的概念,也就是说它们并不互斥。例如,你可以有一个基于XML的web服务作为消息队列的接口。我认为您所寻找的区别是消息队列与请求/响应,后者是在同步处理请求时。

当你使用web服务时,你有一个客户端和一个服务器:

如果服务器出现故障,客户端必须负责处理错误。 当服务器重新工作时,客户端负责重新发送服务器。 如果服务器对调用做出响应,而客户端失败,则操作将丢失。 你不会有争用,也就是说:如果一秒钟内有数百万个客户端在一台服务器上调用web服务,那么你的服务器很可能会瘫痪。 您可以期望服务器立即响应,但也可以处理异步调用。

当你使用像RabbitMQ, Beanstalkd, ActiveMQ, IBM MQ Series, Tuxedo这样的消息队列时,你会期望不同的和更容错的结果:

If the server fails, the queue persist the message (optionally, even if the machine shutdown). When the server is working again, it receives the pending message. If the server gives a response to the call and the client fails, if the client didn't acknowledge the response the message is persisted. You have contention, you can decide how many requests are handled by the server (call it worker instead). You don't expect an immediate synchronous response, but you can implement/simulate synchronous calls.

消息队列有更多的特性,但这是一些经验法则,可以决定您是希望自己处理错误条件,还是将其留给消息队列。

最近有相当多的研究在考虑REST HTTP调用如何取代消息队列概念。

如果引入流程和任务作为资源的概念,对中间消息传递层的需求就开始消失了。

Ex:

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

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

这非常简单,当您意识到现在可以订阅所有正在运行的进程和任务的rss/atom提要而无需任何中间层时,这就变得非常强大。任何排队系统都需要某种类型的web前端,而这个概念在没有另一层自定义代码的情况下内置了它。

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

您已经内置了服务发现,即使对于具有多个步骤的任务,也不需要任何额外复杂的协议。

GET /task/name
    - returns form with required fields

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

您的服务发现是一个HTML表单——一种通用的、人类可读的格式。

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

考虑了一段时间后,您就会开始意识到REST可能完全消除了对消息队列和ESB的需求。

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