在什么条件下,人们会通过消息队列而不是通过Web服务来讨论应用程序(我只是指XML或JSON或YAML或者这里的HTTP,而不是任何特定类型)?
我必须在本地网络上的两个应用程序之间进行交谈.一个将是一个Web应用程序,必须在另一个应用程序(在不同的硬件上运行)上请求命令.这些请求包括创建用户,移动文件和创建目录.在什么条件下我更喜欢使用XML Web Services(或直接TCP或其他东西)来使用Message队列?
Web应用程序是Ruby on Rails,但我认为这个问题比这更广泛.
当您使用Web服务时,您有一个客户端和一个服务器:
如果服务器出现故障,客户端必须负责处理错误.
当服务器再次工作时,客户端负责重新发送它.
如果服务器给出对呼叫的响应并且客户端失败,则操作将丢失.
您没有争用,即:如果数百万客户端在一秒钟内在一台服务器上调用Web服务,则很可能您的服务器将停止运行.
您可以期待服务器立即响应,但您也可以处理异步调用.
当您使用像RabbitMQ,Beanstalkd,ActiveMQ,IBM MQ Series,Tuxedo这样的消息队列时,您期望获得不同的和更多容错结果:
如果服务器出现故障,队列将保留该消息(可选,即使计算机关闭).
当服务器再次工作时,它会收到待处理的消息.
如果服务器给出对呼叫的响应并且客户端失败,则如果客户端未确认响应,则消息将保持不变.
您有争用,您可以决定服务器处理多少请求(改为称之为工作者).
您不希望立即进行同步响应,但可以实现/模拟同步调用.
消息队列具有更多功能,但这是一些经验法则,可以决定您是自己处理错误条件还是将它们留给消息队列.
在考虑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.为Web创建的每个工具都可以驱动您的业务流程.通过异步POST到单独的日志服务器阵列,您仍然可以使用备用消息通道.
在您考虑了一段时间之后,您坐下来开始意识到REST可能只是消除了对消息传递队列和ESB的需求.
http://www.infoq.com/presentations/BPM-with-REST
消息队列非常适合可能需要很长时间才能处理的请求.请求排队,可以脱机处理而不会阻止客户端.如果客户端需要通知完成,您可以为客户端提供定期检查请求状态的方法.
消息队列还允许您跨时间更好地扩展.它提高了处理繁重活动爆发的能力,因为实际处理可以跨时间分布.
请注意,消息队列和Web服务是正交概念,即它们不是互斥的.例如,您可以拥有基于XML的Web服务,该服务充当消息队列的接口.我认为您寻找的区别是消息队列与请求/响应,后者是同步处理请求的时间.
消息队列是异步的,如果传递失败,可以重试多次.如果请求者不需要等待响应,请使用消息队列.
短语"Web服务"让我想到通过HTTP对分布式组件的同步调用.如果请求者需要回复,请使用Web服务.
我想一般来说,你需要一个用于阻塞任务的Web服务(这个任务需要在我们执行更多代码之前完成),以及一个用于非阻塞任务的消息队列(可能需要一段时间,但我们不要不需要等待它.