消息队列与Web服务?

时间:2010-03-05 01:12:33

标签: web-services message-queue

在什么条件下,人们会通过消息队列而不是通过Web服务来讨论应用程序(我只是指XML或JSON或YAML或者其他什么样的HTTP,而不是任何特定的类型)?

我必须在本地网络上的两个应用程序之间进行交谈。一个是Web应用程序,必须在另一个应用程序(在不同的硬件上运行)上请求命令。这些请求包括创建用户,移动文件和创建目录。在什么条件下我更喜欢使用XML Web Services(或直接TCP或其他东西)来使用Message队列?

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

5 个答案:

答案 0 :(得分:301)

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

  1. 如果服务器出现故障,客户端必须负责处理错误。
  2. 当服务器再次运行时,客户端负责重新发送它。
  3. 如果服务器给出了对呼叫的响应,并且客户端失败,则操作将丢失。
  4. 您没有争用,即:如果数百万客户端在一秒钟内在一台服务器上调用Web服务,则很可能您的服务器将停止运行。
  5. 您可以期待服务器立即响应,但您也可以处理异步调用。
  6. 当您使用像RabbitMQ,Beanstalkd,ActiveMQ,IBM MQ Series,Tuxedo这样的消息队列时,您期望获得不同的容错结果:

    1. 如果服务器出现故障,则队列会保留该消息(可选,即使计算机已关闭)。
    2. 当服务器再次运行时,它会收到待处理的消息。
    3. 如果服务器给出了对呼叫的响应并且客户端失败,如果客户端没有确认响应,则消息将保持不变。
    4. 您有争用,您可以决定服务器处理多少请求(改为称之为工作人员)。
    5. 您不希望立即进行同步响应,但可以实现/模拟同步调用。
    6. Message Queues具有更多功能,但这是一些经验法则,可以决定您是想自己处理错误条件还是将它们留给消息队列。

答案 1 :(得分:72)

最近有很多关于考虑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提要而没有任何中间层时,它变得非常强大。无论如何,任何排队系统都需要某种类型的Web前端,而这个概念是内置的,没有另一层自定义代码。

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

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

GET /task/name
    - returns form with required fields

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

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

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

在您考虑一段时间之后,您会坐下来开始意识到REST可能只是消除了对消息传递队列和ESB的需求。

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

答案 2 :(得分:31)

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

消息队列还允许您跨时间更好地扩展。它提高了处理繁重活动爆发的能力,因为实际处理可以跨时间分布。

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

答案 3 :(得分:23)

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

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

答案 4 :(得分:22)

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