一、MQ简介
1.1 什么是MQ
消息:是MQ中最小的概念,本质就是一段数据。
队列:在MQ中使用队列的数据结构来存储消息。
MQ是把消息和队列结合起来,称为消息队列(Message Queue),是基础数据结构中“先进先出”的一种数据结构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。
1.2 MQ的应用场景
应用解耦
系统的耦合性越高,容错性就越低。以电商应用为例,用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障或者因为升级等原因暂时不可用,都会造成下单操作异常,影响用户使用体验。
串行方式注册流程:
并行方式注册流程:
异步解耦方式:
消息发送到MQ后,会立即向客户端发出响应。响应的内容通常是关于消息是否成功接收、处理状态以及可能的错误信息。
流量削峰
应用系统如果遇到系统请求流量的瞬间猛增,有可能会将系统压垮。有了消息队列可以将大量请求缓存起来,分散到很长一段时间处理,这样可以大大提高系统的稳定性和用户体验。 举例:业务系统正常时段的QPS如果是1000,流量最高峰是10000,为了应对流量高峰配置高性能的服务器显然不划算,这时可以使用消息队列对峰值流量削峰。
1.3 各大MQ产品比较
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
producer-consumer | 支持 | 支持 | 支持 | 支持 |
发布-订阅 | 支持 | 支持 | 支持 | 支持 |
API完备性 | 高 | 高 | 高 | 高 |
多语言支持 | 支持,Java优先 | 语言无关 | 只支持Java | 支持,Java优先 |
单机吞吐量 | 万级 | 万级 | 万级 | 十万级 |
消息延迟 | 微秒级 | 毫秒级 | 毫秒级 | |
可用性 | 高(主从) | 高(主从) | 非常高(分布式) | 非常高(分布式) |
消息丢失 | 低 | 低 | 理论上不会丢失 | 理论上不会丢失 |
消息重复 | 可控制 | 理论上会有重复 | ||
文档完备性 | 高 | 高 | 高 | 高 |
提供快速入门 | 有 | 有 | 有 | 有 |
部署难度 | 低 | 低 | 中 | |
社区活跃度 | 高 | 高 | 中 | 高 |
商业支持 | 无 | 无 | 阿里云 | 无 |
成熟度 | 成熟 | 成熟 | 成熟 | 成熟(日志领域) |
特点 | 功能齐全,大量项目使用 | 借助于erlang语言并发能力,性能高 | 各环节分布式设计,主从HA,支持上万队列,多种消费模式,性能好 | |
支行协议 | openwire,stomp,rest,xmpp,amqp | amqp | 自定义的一套(社区提供JMS--不成熟) | |
持久化 | 内存,文件,数据库 | 内存,文件 | 磁盘文件 | |
事务 | 支持 | 支持 | 支持 | |
负载均衡 | 支持 | 支持 | 支持 | |
管理界面 | 一般 | 好 | 有web console实现 | |
部署方式 | 独立,嵌入 | 独立 | 独立 | |
评价 | 优点:成熟的产品,已经在很多公司应用但规模不大,各种协议支持较好,有多重语言的客户端;缺点:其重点已放到activemq6.0产品appollo上去了,目前社区不活跃,且对5.x的维护较少;不适用于上千队列场景 | 优点:由于erlang语言的特点,产品性能较好,在互联网公司有较大规模应用,支持amqp协议,有多语言且支持amqp的客户端可用;缺点:erlang语言难度大,集群不支持动态扩展 | 优点:模型简单,接口易用,在阿里大规模应用;性能好,可大量堆积消息在broker中,支持多种消费,包括集群消费,广播消费,开发活跃度高,版本更新快;缺点:没有在mq核心中实现JMS等接口,有些系统要迁移需要修改大量代码;支持的客户端语言不多,目前是java及c++,其中c++不成熟; | 优点:性能卓越,单机写入TPS约在百万条/秒,最大的优点,就是吞吐量高。在日志领域比较成熟,被多家公司和多个开源项目使用;缺点:Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长;消费失败不支持重试;支持消息顺序,但是一台代理宕机后,就会产生消息乱序;社区更新较慢; |
1.4 发展历程(了解即可,纯属乱扯)
1.5 概念术语
- 生产者和消费者
生产者负责生产消息,一般由业务系统负责生产消息,消费者即后台系统,它负责消费消息。这里的信箱就相当于是消息中间件,小明就是消息的生产者,邮递员就是消息的消费者。
- 消息模型(Message Model)
消息模型主要有队列模型和发布订阅模型,RabbitMQ采用的是队列模型,如下图所示:
RocketMQ采用发布订阅模型,模型如图所示:
- 主题(Topic)
表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。就好比是我们订阅的刊物,有科技类的刊物、财经类的刊物、军事类的刊物等等。这些刊物的类型实际上就是消息的主题。
- 代理服务器(Broker Server)
消息中转角色,负责存储消息、转发消息。例如中国邮政负责消息的中转。
- 名字服务(Name Server)
相当于一个管理机构。本身不做消息的存储和转发工作,名称服务管理代理服务器broker
- 生产者组(Producer Group)
同一类Producer的集合,这类Producer发送同一类消息且发送逻辑一致。
- 消费者组(Consumer Group)
同一类Consumer的集合,这类Consumer通常消费同一类消息且消费逻辑一致。
- 拉取式消费(Pull Consumer)
Consumer消费的一种类型,应用通常主动调用Consumer的拉消息方法从Broker服务器拉消息、主动权由应用控制。一旦获取了批量消息,应用就会启动消费过程。
- 推动式消费(Push Consumer
Consumer消费的一种类型,该模式下Broker收到数据后会主动推送给消费端,该消费模式一般实时性较高。
- 普通顺序消息(Normal Ordered Message)
普通顺序消费模式下,消费者通过同一个消息队列( Topic 分区,称作 Message Queue) 收到的消息是有顺序的,不同消息队列收到的消息则可能是无顺序的。
- 严格顺序消息(Strictly Ordered Message)
严格顺序消息模式下,消费者收到的所有消息均是有顺序的。