目录
1:什么是消息队列
2:MQ的基础模型
3:MQ的作用
3.1:MQ用来解耦
3.2: 削峰填谷
4:MQ怎么选
1:什么是消息队列
MQ全称是Message Queue (消息队列),是消息传输中间件,用在分布式系统中消息传输过程中保存消息的容器。
2:MQ的基础模型
生产者将消息发送到消息队列,消息队列保存消息,消息队列将消息发送给消费者,又或者消费者去消息队列拉取消息。生产者和消费者称为客户端,相对应的MQ就是服务端。
3:MQ的作用
3.1:MQ用来解耦
在微服务中分布式系统中,我们直接调用的存在调用链路复杂,使用MQ能解耦各个系统,降低耦合性,比如订单系统的下单和减库存。使用mq,下单在订单系统完成,减库存操作发送到MQ,提高并发量。
解耦之前
解耦之后
解耦带来的好处就是速度的提升:
之前请求时间:50ms*4=200ms
之后请求时间
3.2: 削峰填谷
系统没有使用mq的直接操作数据的时候,最大并发量是1000/S,当出现大并发的时候5000/S的时候,系统报错,比如数据库连接池不够用等错误。我们把这5000/S的请求打到MQ,这就是削峰。
MQ的消费者以固定的速度消费消息,比如2000/S。将MQ积压的消息消费完毕,这就是填谷。
4:MQ怎么选
市面上免费的MQ产品主要有RocketMQ、ActiveMQ、Kafka和RabbitMQ。
这几种MQ怎么选择呢?我们需要知道他们的技术特点然后结合自己的需求来选择。
我们列出这四种MQ的技术特点,然后根据需求选择。
Kafka的优缺点
优点:
-
高吞吐量:即使在非常廉价的机器上,Kafka也能做到每秒处理几十万条消息,而它的延迟最低只有几毫秒。
-
低延迟:延迟可以控制在ms以内。
-
持久性:Kafka可以将消息直接持久化在普通磁盘上,且磁盘读写性能优异。
-
扩展性。Kafka集群支持热扩展,Kaka集群启动运行后,用户可以直接向集群中添加。
-
容错性。Kafka会将数据备份到多台服务器节点中,即使当某个服务器节点失效时,Zookeeper将通知生产者和消费者从而使用其他的节点,也不会影响整个系统的功能。
-
支持多种客户端语言。Kafka支持Java、.NET、PHP、Python等多种语言。
缺点:
-
重复消息:Kafka保证每条消息至少送达一次,虽然几率很小,但一条消息可能被送达多次。
-
消息乱序:Kafka某一个固定的Partition内部的消息是保证有序的,如果一个Topic有多个Partition,partition之间的消息送达不保证有序。
-
复杂性:Kafka需要Zookeeper的支持,Topic一般需要人工创建,部署和维护比一般MQ成本更高。
-
topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源。
RabbitMQ的优缺点
优点:
-
持久化:RabbitMQ可以保证所在的服务器宕机后,消息不会丢失。
-
高可用:部分机器宕机了还可以继续使用。
-
高级功能:如消息重试、死信队列等
缺点:
-
首先是RabbitMQ吞吐量比较低,大概在每秒几万的样子,这样像对于大型电商促销秒杀就不能胜任。
-
集群线性扩展比较麻烦。
-
开发语言是erlang,懂得人不是很多,无法对其改造。
RocketMQ的优缺点
优点:
-
高吞吐量:大概普通机器有十万QPS往上。
-
消息可靠性:
-
生产者的可靠性保证:生产者发送消息后返回SendResult,如果isSuccess返回true,则表示消息已经确认发送到服务器并被服务器接收保存。整个发送过程是一个同步过程。
-
服务器的可靠性:消息生产者发送的消息,RocketMQ服务收到后在做必要的校验和检查之后马上保存到磁盘,写入成功后返回给生产者。因此可以确认每条发送结果为成功的消息都会被消息服务器写入磁盘。
-
消费者的可靠性:消费者是一条一条顺序消费的,之后在成功消费一条后才会消费吓一跳。如果在消费某一条消息时失败则会重试消费这条消息,默认为5次,如果超过最大次数仍然无法消费,则将消息保存到本地,后台线程继续重试消费,主线程则会继续往后走,消费队列后面的消息。
-
-
消息持久性:RocketMQ收到消息后,会将消息持久化到文件,并利用Linux文件系统内存来提高性能
-
消息实时性:RocketMQ采取长轮询+PULL模式保证消息的实时性
-
消息堆积:支持10亿级别的消息堆积,不会因为消息堆积影响性能
-
高级功能:如延迟消息、消息回朔等
-
使用的java开发
缺点:
-
消息重复:对于消费者来说,通过拉取方式将消息保存到本地,消费完再向服务器返回,在网络异常的情况下可能会出现重复。
-
消息过滤:
-
服务器端过滤:减少不必要消息传输,但是会增加服务器负担
-
客户端过滤:根据客户端需求来定制消息,缺点是客户端会收到对它来说没用的消息,如果客户端无法承载这么多消息就会导致故障