消息队列简单介绍

为什么要使用队列系统?

  • 因为一些任务需要在后台执行,让调用者不需要等待其完成就能返回。比如给用户发送邮件,短信之类的操作。
  • 还有就是一个大系统内部的通信,可能会采用队列的方式传递消息。

对队列系统有哪些要求?

  • 应对任务处理者:通常会有一些进程从队列里获取消息进行处理,而且通常这些进程都会启动很多个。所以队列需要能够处理并发的数据请求操作。
  • 原子性:队列中的元素只能被取出一次,必须保证每次读取队列中元素进行操作和删除这个元素是原子性的。
  • 快速:队列系统要能够快速地处理元素的写入和读取操作。
  • 垃圾回收能力:如果一个任务处理到一半死掉了,那么必须能有方法监测到并且将这个任务重新放入队列中。


redis VS mongoDB

对于原子性,RabbitMQ通过对consume/ack协议的支持来实现。而由于MongoDB只支持对单个文档的原子性个性,所以你可以使用其findAndModify 命令 ,简单语法如下:

db.runCommand( { findAndModify : collection, { options } } )

这里的options是一个数组,其包含下面一些元素:

其它的一些考虑

除了上面说到的速度,原子性等特性,对于一个队列系统,还是有一些其它方面需要考虑的。

  • 容错性:MongoDB的replica sets 架构提供了整体的高可用性。当其被用作队列时,也同样继承了这一我。而RabbitMQ并没有内置的支持。目前在RabbitMQ 2.6.0中有相关的支持
  • 一致性:MongoDB默认会一分钟将数据flush到磁盘,但其同时提供一个默认100ms的操作日志可以增强其单机的可靠性。可以缓解宕机时数据丢失导致不一至的情况。如果你对一致性要求非常高,你也可以使用MongoDB的getLastError 命令来保证你的每次操作都写入操作日志或者磁盘上才返回成功。
  • 扩展性:我们使用capped collection 来做消息队列,所以老数据的清除是自动的。在MongoDB中可以通过sharding 方式来实现数据的横向扩展,但是sharding并不支持用于capped collection 。你可以自己选择自己需要的应用方式。

猜你喜欢

转载自san-yun.iteye.com/blog/1715317