上面提到的异步处理,跟日志系统似乎搭配起来也很好。特别是当你需要把日志发往单独的数据平台的时候,「消息队列」尤为有用,我们不再需要在业务代码里面侵入我们的各种打点or日志,只需要简单的发布一条消息,再去关注做处理就好了。
场景四:应用解耦基于上面的例子你应该也能感受一二了。
场景三:流量削峰这也是「消息队列」常见的场景,通过引入「消息队列」,我们一来可以控制请求的人数,二来也可以缓解短时间内高流量的压力。
场景四:消息通讯消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。
四、常见消息队列中间件 如果自己设计一个?我们在讨论市面上常见的「消息队列」中间件之前,我们先来考虑自己造一个怎么样?如果是你自己来设计,你会怎么做?乍一想,似乎每个语言都会有自己实现的「队列」,往队列里塞数据,再从队列里面挨个取就行了?
但是一细想好像事情并不简单。作为一个「消息队列」,你首先要保证数据不能给人家弄丢了吧?存内存?万一断电了怎么办?写磁盘?消息量超过系统写磁盘速率上限了怎么办?备份又该怎么做呢?
好,假设我一整捣鼓,保证了我的数据不会丢失了,下一个问题,生产者怎么往「消息队列」里面塞数据?我的意思是,生产者可能不止一个,把全量的消息放在一个队列似乎不太合适,我需要给这些消息分个类吧?新来了一个分类的消息我怎么动态的扩容呢?消费者又如何消费这些数据呢?多个消费者之间又如何进行协调呢?
好吧..总之问题挺多的..并不像表面那么简单。
RabbitMQRabbitMQ 是使用 Erlang 编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正因如此,它非常重量级,更适合于企业级的开发。同时实现了 Broker 构架,这意味着消息在发送给客户端时先在中心队列排队。对路由,负 载均衡或者数据持久化都有很好的支持。
RedisRedis 也能用来做「消息队列」。Redis 是一个基于 Key-Value 对的 NoSQL 数据库,开发维护很活跃。虽然它是一个 Key-Value 数据库存储系统,但它本身支持 MQ 功能, 所以完全可以当做一个轻量级的队列服务来使用。对于 RabbitMQ 和 Redis 的入队和出队操作,各执行 100 万次,每 10 万次记录一次执行时间。测试 数据分为 128 Bytes、512 Bytes、1 K和 10 K四个不同大小的数据。实验表明:入队时,当数据比较小时 Redis 的性能要高于 RabbitMQ,而如果数据大小超过了 10 K,Redis 则慢的无法忍受;出队时,无论数据大小,Redis 都表现出非常好的性能,而 RabbitMQ 的出队性能则远低于Redis。
Kafka/JafkaKafka 是 Apache 下的一个子项目,是一个高性能跨语言分布式 Publish/Subscribe 消息队列系统,而 Jafka 是在 Kafka 之上孵化而来的,即 Kafka 的一个升级版。
具有以下特性:
快速持久化,可以在O(1)的系统开销下进行消息持久化;
高吞吐,在一台普通的服务器上既可以达到 10 W/s的吞吐速率;
完全的分布式系统,Broker、Producer、Consumer都原生自动支持分布式,自动实现复杂均衡;
支持 Hadoop 数据并行加载,对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。
Kafka 通过 Hadoop 的并行加载机制来统一了在线和离线的消息处理。Apache Kafka 相对于 ActiveMQ 是一个非常轻量级的消息系统,除了性能非常好之外,还是一个工作良好的分布式系统。
ZeroMQZeroMQ 号称最快的消息队列系统,尤其针对大吞吐量的需求场景。ZeroMQ 能够实现 RabbitMQ 不擅长的高级 / 复杂的队列,但是开发人员需要自己组合多种技术框架,技术上的复杂度是对这 MQ 能够应用成功的挑战。ZeroMQ 具有一个独特的非中间件的模式,你不需要安装和运行一个消息服务器或中间件,因为你的应用程序将扮演这个服务器角色。你只需要简单的引用 ZeroMQ 程序库,可以使用 NuGet 安装,然后你就可以愉快的在应用程序之间发送消息了。但是 ZeroMQ 仅提供非持久性的队列,也就是说如果宕机,数据将会丢失。其中,Twitter 的 Storm 0.9.0 以前的版本中默认使用 ZeroMQ 作为数据流的传输(Storm 从 0.9 版本开始同时支持 ZeroMQ 和 Netty 作为传输模块)。
ActiveMQ