1、MQ介绍
1.1、什么是消息队列
消息队列(Message Queue)是一种进程间通信或同一进程的不同线程间的通信方式。通俗点来讲的话,消息队列就是一个存放消息的容器,是一种“先进先出”的数据结构
1.2、什么时候需要消息队列
1.2.1、异步处理
场景说明: 用户注册后,需要发送注册的邮件和注册的短信。
1.2.2、应用解耦
场景说明: 用户下单后,订单系统需要通知库存系统和支付系统。传统的做法是,订单系统调用库存系统和支付系统的接口。但是传统的做法可能导致失败,引入消息队列,将订单系统与支付系统等解耦
1.2.3、流量削峰
流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛
应用场景: 秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。有了消息队列可以将大量请求缓存起来,分散请求
1.2.4、内容分发
通过消息队列可以让数据在多个系统更加之间进行流通。数据的产生方不需要关心谁来使用数据,只需要将数据发
Rocket的架构
- Name Server:相当于注册中心,更新和发现 Broker 服务
- Broker:消息中转角色,负责存储消息,转发消息。 分为 Master Broker 和 Slave Broker,一个 Master Broker 可以对应多个 Slave Broker,但是一个 Slave Broker 只能对应一个 Master Broker。
- 生产者:同Name Server中的一个节点建立长连接,定期从 Name Server 读取 Topic 路由信息,并向提供 Topic 服务的 Master Broker 建立长链接
- 消费者:与 Name Server 中的其中一个节点(随机)建立长连接,定期从 Name Server 拉取 Topic 路由信息,并向提供 Topic 服务的 Master Broker、Slave Broker 建立长连接,且定时向 Master Broker、Slave Broker 发送心跳。
Rocket消息类型
普通消息(同步、异步、单向),顺序消息,定时消息,事务消息
1.3 MQ的优点和缺点
优点:异步处理、解耦、削峰、数据分发
缺点包含以下几点:
-
系统可用性降低
系统引入的外部依赖越多,系统稳定性越差。一旦MQ宕机,就会对业务造成影响。
如何保证MQ的高可用?
-
系统复杂度提高
MQ的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过MQ进行异步调用。
如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?
-
一致性问题
A系统处理完业务,通过MQ给B、C、D三个系统发消息数据,如果B系统、C系统处理成功,D系统处理失败。
如何保证消息数据处理的一致性?
1.4 选择消息队列的基本标准
一款及格的消息队列,必须具备的几个特性包括:
- 消息的可靠传递:确保不丢消息;
- Cluster:支持集群,确保不会因为某个节点宕机导致服务不可用,当然也不能丢消息;
- 性能:具备足够好的性能,能满足绝大多数场景的性能要求。
接下来看一下有哪些符合上面这些条件,可供选择的开源消息队列。
1.4.1 RabbitMQ
简单来说就是轻量化,容易部署和使用,它最早是为电信行业系统设计的,而且支持非常灵活的路由配置,它在生产者(Producer)和队列(Queue)之间增加了一个 Exchange 模块,可以理解为交换机。
而且RabbitMQ 的客户端支持的编程语言是最多的
接下来说下 RabbitMQ 的几个缺点:
- RabbitMQ 对消息堆积的支持并不好,当大量消息积压的时候,会导致 RabbitMQ 的性能急剧下降。
- RabbitMQ 的性能差,大概每秒钟可以处理几万到十几万条消息。如果应用对消息队列的性能要求非常高,那不要选择 RabbitMQ。
- RabbitMQ 使用的编程语言 Erlang,扩展和二次开发成本高。
1.4.2 RocketMQ
RocketMQ 是阿里巴巴开源的,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进
RocketMQ 有着不错的性能,稳定性和可靠性,具备一个现代的消息队列应该有的几乎全部功能和特性,并且它还在持续的成长中。
RocketMQ 有非常活跃的中文社区,并且容易对 RocketMQ 进行扩展或者二次开发。
毫秒级的响应,每秒钟大概能处理几十万条消息。
RocketMQ 的劣势是与周边生态系统的集成和兼容程度不够。
1.4.3 Kafka
Apache Kafka 是一个分布式消息发布订阅系统。
Kafka 与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域,几乎所有的相关开源软件系统都会优先支持 Kafka。
Kafka 性能高效、可扩展良好并且可持久化。它的分区特性,可复制和可容错都是不错的特性。
Kafka 使用 Scala 和 Java 语言开发,设计上大量使用了批量和异步的思想,使得 Kafka 能做到超高的性能。Kafka 的性能,尤其是异步收发的性能,是三者中最好的,但与 RocketMQ 并没有量级上的差异,大约每秒钟可以处理几十万条消息。
在有足够的客户端并发进行异步批量发送,并且开启压缩的情况下,Kafka 的极限处理能力可以超过每秒 2000 万条消息。
但是 Kafka 异步批量的设计带来的问题是,它的同步收发消息的响应时延比较高,因为当客户端发送一条消息的时候,Kafka 并不会立即发送出去,而是要等一会儿攒一批再发送,在它的 Broker 中,很多地方都会使用这种先攒一波再一起处理的设计。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。所以,Kafka 不太适合在线业务场景。
1.5 各种MQ产品的比较
常见的MQ产品包括RabbitMQ、RocketMQ、Kafka。
| 特性 | RabbitMQ | RocketMQ | Kafka |
|---|---|---|---|
| 开发语言 | erlang | java | scala |
| 单机吞吐量 | 万级 | 十万级 | 十万级 |
| 时效性 | us级 | ms级 | ms级以内 |
| 可用性 | 高(主从架构) | 很高(分布式架构) | 很高(分布式架构) |
| 可靠性 | 基本不丢 | 经过参数优化配置,可以做到 0 丢失 | 经过参数优化配置,可以做到 0 丢失 |
| 功能特性 | 基于 erlang 开发,并发能力很强,性能极好,延时很低 | MQ 功能较为完善,还是分布式的,扩展性好 | 只支持主要的MQ的功能, 像一些消息队列的信息查询,消息回溯等功能没有提供, 毕竟是为大数据准备的,在大数据领域应用广。 |
中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司(我们公司肯定是要往这个方向发展的),基础架构研发实力较强,用 RocketMQ 是很好的选择。
如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。