消息队列概念与认知

MQ学习系列:

  1. 消息队列概念与认知
  2. ActiveMQ Topic消息重发
  3. ActiveMQ Topic 持久化订阅
  4. zookeeper+ActiveMQ集群实现高可用

本文是-消息队列学习的概念与介绍篇。目的是能够对消息队列能够有一个简单的了解和大体的认知。

参考/学习资料整理(好东西要学会分享 )

B站上的黑马ActiveMQ的视频教程

Hollis公众号上的消息队列文章

架构之家公众号上的消息队列文章

JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目)

CS-Notes(技术面试必备基础知识)

JCSprout(处于萌芽阶段的 Java 核心知识库)

一个在线绘图的工具

一、消息队列简介

消息队列 MQ(message queue)中间件是分布式系统中的重要组件,主要解决异步消息、应用解耦、流量 削峰等问题,从而实现高性能、高可用 ,可伸缩和最终一致性的架构。

使用较多的消息队列有ActiveMQ 、RabbitMQ、RocketMQ、Kafka、MetaMQ等

1 消息队列应用场景分析

1.1 异步处理

举个栗子:

有这样一个用户注册场景 ,实现将注册信息写入数据库并发送邮件和注册短信的功能。

传统的方式如图:

消息队列-传统.PNG

这样的方式会一步步按照先后顺序 完成后返回给用户信息 ,整个过程用户都处于等待的状态,并用时150ms。

而引用消息对列 ,异步处理,改造后的架构如下

消息队列-改进.PNG

这样对于用户的响应时间就大大减少了。

1.2 应用解耦

多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败。

消息队列-应用解耦.png

1.3 流量削峰

广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况。

具体场景:购物网站开展秒杀活动,一般由于瞬时访问量过大,服务器接收过大,会导致流量暴增,相关系统无法处理请求甚至崩溃。而加入消息队列后,系统可以从消息队列中取数据,相当于消息队列做了一次缓冲。

二、JMS & AMQP

1 JMS 简介

JMS(JAVA Message Service,java消息服务)是java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输。JMS(JAVA Message Service,Java消息服务)API是一个消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。

ActiveMQ 就是基于 JMS 规范实现的。

2 JMS 消息模型

2.1 P2P(point to point)点对点模式

P2P模式包含三个角色:消息队列(Queue)、发送者(Sender)、接收者(Receiver)。每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留消息 ,直到他们被消费或超时。

消息队列-P2P模型.png

P2P的特点:

  • 每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)。
  • 发送者和接收者之间在时间上没有依赖性,也就是说当大发送者发送了消息之后,不管接收者有没有正在运行 ,他不会影响到消息被发送到队列。
  • 接收者在成功接收消息之后需向队列应答成功。

如果希望发送的每个消息都会被成功处理的话,那么需要P2P模式。

2.2 Publish/Subscribe(Pub/Sub)发布订阅模式

Pub/Sub模式包含三个角色:主题(Topic)、发布者(Publisher)、订阅者(Subscriber)。多个 发布者将消息发布到Topic,系统将这些消息传递给多个订阅者。

![消息队列-pub/sub.jpg

Pub/Sub的特点:

  • 每个消息可以有多个消费者。
  • 发布者和订阅者之间没有时间上的依赖性,针对某个主题(Topic)的订阅者,他必须创建一个订阅之后,才能消费发布者的消息。
  • 为了消费消息,订阅者必须保持运行的状态。[为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样即使订阅者没有被激活(运行),它也能收到发布者发布的消息。]

如果希望发送的消息可以被多个消费者处理的话,那么可以采用Pub/Sub模型。

2.3 JMS 五种不同的正文消息格式

JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。

  • StreamMessage -- Java原始值的数据流
  • MapMessage--一套名称-值对
  • TextMessage--一个字符串对象
  • ObjectMessage--一个序列化的 Java对象
  • BytesMessage--一个字节的数据流

3 AMQP

3.1 AMQP简介

AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准 高级消息队列协议(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。

RabbitMQ 就是基于 AMQP 协议实现的。

4 JMS与AMQP对比

对比方向 JMS AMQP
定义 Java API 协议
跨语言
跨平台
支持消息类型 提供两种消息模型:①Peer-2-Peer;②Pub/sub 提供了五种消息模型:①direct exchange;②fanout exchange;③topic change;④headers exchange;⑤system exchange。本质来讲,后四种和JMS的pub/sub模型没有太大差别,仅是在路由机制上做了更详细的划分;
支持消息类型 支持多种消息类型 ,我们在上面提到过 byte[](二进制)

总结:

  • AMQP 为消息定义了线路层(wire-level protocol)的协议,而JMS所定义的是API规范。在 Java 体系中,多个client均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差。而AMQP天然具有跨平台、跨语言特性。
  • JMS 支持TextMessage、MapMessage 等复杂的消息类型;而 AMQP 仅支持 byte[] 消息类型(复杂的类型可序列化后发送)。
  • 由于Exchange 提供的路由算法,AMQP可以提供多样化的路由方式来传递消息到消息队列,而 JMS 仅支持 队列 和 主题/订阅 方式两种。

三、常见消息队列对比总结

对比方向 概要
吞吐量 万级的 ActiveMQ 和 RabbitMQ 的吞吐量(ActiveMQ 的性能最差)要比 十万级甚至是百万级的 RocketMQ 和 Kafka 低一个数量级。
可用性 都可以实现高可用。ActiveMQ 和 RabbitMQ 都是基于主从架构实现高可用性。RocketMQ 基于分布式架构。 kafka 也是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
时效性 RabbitMQ 基于erlang开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。其他三个都是 ms 级。
功能支持 除了 Kafka,其他三个功能都较为完备。 Kafka 功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准
消息丢失 ActiveMQ 和 RabbitMQ 丢失的可能性非常低, RocketMQ 和 Kafka 理论上不会丢失。

总结:

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

四、更多参考资料汇总[粘贴狂魔 (﹁"﹁)(﹁"﹁)(﹁"﹁)]

1 消息队列:

  1. 大型网站架构之分布式消息队列 http://blog.csdn.net/shaobingj126/article/details/50585035
  2. 消息队列的使用场景 https://www.zhihu.com/question/34243607/answer/127666030
  3. 浅谈异步消息队列模型 http://www.cnblogs.com/sunkeydev/p/5248855.html
  4. 消息队列的两种模式 http://blog.csdn.net/heyutao007/article/details/50131089

2 RabbitMQ

  1. RabbitMQ主页 https://www.rabbitmq.com/
  2. RabbitMQ学习教程 https://www.rabbitmq.com/getstarted.html
  3. 专栏:RabbitMQ从入门到精通 http://blog.csdn.net/column/details/rabbitmq.html
  4. RabbitMQ能为你做些什么 http://rabbitmq.mr-ping.com/description.html
  5. RabbitMQ指南(1)-特性及功能 https://blog.zenfery.cc/archives/79.html

3 ActiveMQ

  1. ActiveMQ主页 http://activemq.apache.org/
  2. Apache ActiveMQ介绍 http://jfires.iteye.com/blog/1187688
  3. ActiveMQ的简介与安装 http://blog.csdn.net/sl1992/article/details/72824562
  4. ActiveMQ 和消息简介 http://www.cnblogs.com/craftsman-gao/p/7002605.html

4 RocketMQ

  1. 主页 https://github.com/alibaba/RocketMQ
  2. RocketMQ 原理简介 http://alibaba.github.io/RocketMQ-docs/document/design/RocketMQ_design.pdf
  3. RocketMQ与kafka对比(18项差异) http://jm.taobao.org/2016/03/24/rmq-vs-kafka/

5 Kafka

  1. Kafka主页: http://kafka.apache.org/
  2. Kafka特性 http://www.cnblogs.com/lsx1993/p/4847719.html
  3. Kafka客户端支持语言 https://cwiki.apache.org/confluence/display/KAFKA/Clients

6 RabbitMQ/ActiveMQ/RocketMQ/Kafka对比

  1. RocketMQ,队列选型 http://www.zmannotes.com/index.php/2016/01/17/rocketmq/
  2. RabbitMQ和Kafka http://www.dongcoder.com/detail-416804.html
  3. 即时通信RabbitMQ二-性能测试 http://www.jianshu.com/p/d31ae9e3bfb6
  4. RabbitMq、ActiveMq、ZeroMq、kafka之间的比较,资料汇总 http://blog.csdn.net/linsongbin1/article/details/47781187
  5. 消息队列软件产品大比拼 http://www.cnblogs.com/amityat/archive/2011/08/31/2160293.html
posted @ 2019-01-27 14:15  厨房有只偷吃的猫  阅读(635)  评论(0编辑  收藏  举报