消息队列总结

消息队列和消息

“消息队列”(Message queue)是在消息的传输过程中保存消息的容器。“消息” 是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。

消息队列又称消息中间件(区别于本地消息队列,本地消息队列指的是JVM内的队列实现) ,是一种独立的队列系统,消息中间件经常用来解决内部服务之间的 异步调用问题

常见的消息队列

当前使用较多的消息队列有RabbitMQActiveMQRocketMQKafka等等,当然redis数据库也可以实现消息队列,不过不推荐,redis本身设计就不是用来做消息队列的。

消息队列使用场景

  • 异步调用:

    mq1

在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。

  • 解耦 : 一个业务的非核心流程需要依赖其他系统,但结果并不重要,有通知即可。

    分布式系统模块之间耦合的两种方式:分布式消息队列 和 分布式服务

    • 分布式服务SOAService Oriented Architecture面向服务体系结构

      Dubbo 等分布式服务框架

    • 分布式消息队列:事件驱动架构(生产者—消费者 发布—订阅)

    mq3

    ​ 消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。 从上图可以看到消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计

    另外为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。

  • 最终一致性 : 指的是两个系统的状态保持一致,可以有一定的延迟,只要最终达到一致性即可。经常用在解决分布式事务上。

  • 广播 : 消息队列最基本的功能。生产者只负责生产消息,订阅者接收消息。

  • 错峰和流控

    mq2

消息队列具有很好的削峰作用的功能——即通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。 (秒杀、抢购、抢票等)

消息队列两个重要概念

  1. 消息代理(Message Broker)

    当消息发送者发送消息以后,将由消息代理接管,消息代理保证消息传递到指定目的地。

  2. 目的地(Destination)

    • 队列(queue):点对点消息通信(point-to-point)

      • 消息发送者发送消息,消息代理将其放入一个队列中,消息接收者从队列中获取消息内容,消息读取后被移出队列
      • 消息只有唯一的发送者和接受者,但并不是说只能有一个接收者
    • 主题(topic):发布(publish)/订阅(subscribe)消息通信

      • 发送者(发布者)发送消息到主题,多个接收者(订阅者)监听(订阅)这个主题,那么就会在消息到达时同时收到消息

基本模型

常见消息队列介绍

  • ActiveMQ: ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ是一个完全支持JMS1.1和J2EE 1.4规范的JMSProvider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。

    官网:http://activemq.apache.org/

    具体可以参考:

    《消息队列ActiveMQ的使用详解》

  • RabbitMQ: RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。RabbitMQ 最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗

    AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。

    官网:http://www.rabbitmq.com/

    具体可以参考:

    《消息队列之 RabbitMQ》

  • RocketMQ:RocketMQ是阿里开源的消息中间件,目前在Apache孵化,使用纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,但并不是简单的复制,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景,支撑了阿里多次双十一活动。

    官网:http://rocketmq.apache.org/

    具体可以参考:

    《RocketMQ 实战之快速入门》

    《十分钟入门RocketMQ》 (阿里中间件团队博客)

  • Kafka:Kafka是一个分布式的、可分区的、可复制的、基于发布/订阅的消息系统(现在官方的描述是“一个分布式流平台”),由Scala和Java编写 ,Kafka主要用于大数据领域,当然在分布式系统中也有应用。目前市面上流行的消息队列RocketMQ就是阿里借鉴Kafka的原理、用Java开发而得。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。

    官网:http://kafka.apache.org/

    具体可以参考:

    《Kafka应用场景》

    《初谈Kafka》

总结:

  • ActiveMQ 的社区算是比较成熟,但是较目前来说,ActiveMQ 的性能比较差,而且版本迭代很慢,不推荐使用。
  • RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 和 RocketMQ ,但是由于它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。但是也因为 RabbitMQ 基于 erlang 开发,所以国内很少有公司有实力做erlang源码级别的研究和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这四种消息队列中,RabbitMQ 一定是你的首选。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
  • RocketMQ 阿里出品,Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的MQ,并且 RocketMQ 有阿里巴巴的实际业务场景的实战考验。RocketMQ 社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准 JMS 规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用RocketMQ 挺好的
  • kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。

参考:《Java工程师面试突击第1季-中华石杉老师》

性能对比:

《Kafka、RabbitMQ、RocketMQ等消息中间件的对比 —— 消息发送性能和区别》

最后:

文章参考:

消息队列深入解析

数据通信(RESTful、RPC、消息队列)相关知识点总结.md)

消息队列总结:新手也能看懂,消息队列其实很简单

感谢原作者:SnailClimb