消息队列还是Web服务?

在什么情况下,人们会倾向于通过消息队列而不是通过Web服务(我只是指XML或JSON或YAML或HTTP上的任何内容,而不是任何特定的types)来交stream应用程序?

我必须在本地networking上的两个应用程序之间进行通话。 一个将是一个Web应用程序,并且需要在另一个应用程序(运行在不同的硬件上)的命令。 这些请求就像创build用户,移动文件和创build目录一样。 在什么情况下,我更喜欢XML Web Services(或者直接的TCP或者其他)来使用消息队列?

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

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

  1. 如果服务器出现故障,则客户端必须负责处理该错误。
  2. 当服务器再次工作时,客户端负责重新发送它。
  3. 如果服务器对呼叫作出响应并且客户端失败,则操作丢失。
  4. 你没有争议,那就是:如果有一百万客户在一台服务器上调用一个Web服务,那么很可能你的服务器就会closures。
  5. 您可以期待从服务器立即响应,但您也可以处理asynchronous调用。

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

  1. 如果服务器发生故障,则队列将持续发送消息(可选,即使机器关机)。
  2. 当服务器再次工作时,它接收到挂起的消息。
  3. 如果服务器对呼叫作出响应并且客户端失败,则如果客户端没有确认该响应,则该消息被持续。
  4. 你有争议,你可以决定有多less请求被服务器处理(而不是调用它)。
  5. 你不期望一个即时的同步响应,但你可以实现/模拟同步调用。

消息队列有更多的function,但这是一些经验法则来决定是否要自己处理错误条件或将它们留给消息队列。

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

如果将stream程和任务的概念作为资源引入,则中间消息传递层的需求开始蒸发。

例如:

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 

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

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

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

你已经build立了服务发现,即使对于一个有多个步骤的任务,没有任何额外的复杂协议。

 GET /task/name - returns form with required fields POST (URL provided form's "action" attribute) 

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

整个stream程可以使用普遍接受的工具以编程方式或由人类使用。 这是一个客户驱动的,因此是RESTful。 为networking创build的每个工具都可以推动您的业务stream程。 通过asynchronous发送到单独的日志服务器arrays,您仍然具有备用的消息通道。

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

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

消息队列非常适合需要很长时间处理的请求。 请求排队,可以脱机处理,而不会阻塞客户端。 如果客户端需要通知完成,则可以为客户端定期检查请求的状态。

消息队列还允许您跨越时间进行更好的扩展。 它提高了你处理繁重活动的能力,因为实际的处理可以随时间分配。

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

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

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

我想一般情况下,你会想要一个阻塞任务的Web服务(这个任务需要完成之前,我们执行更多的代码),和一个非阻塞任务的消息队列(可能需要一段时间,但我们不不需要等待)。