消息队列MQ是一种应用程序对应用程序的通信方法。 本质是一种先进先出的数据结构。
一、MQ应用场景
1、解耦
-
应用解耦解决的问题
在如下系统中,如果B、C、D功能发生变化则A系统也要跟着改变,或者是新增系统E时,也需要增加A的调用,这样A系统与B、C、D、E就是耦合在一起的,新增或修改功能就比较麻烦。
添加MQ组件后:
A系统如果要调用B、C、D系统时,只需要将A的请求数据发送到MQ中再由BCD系统区进行消费,添加了MQ之后如果再需要新增修改BCD系统的功能就和A系统关联不大了。
2、异步
- 应用异步解决的问题:
系统没有异步前一个请求给到A系统,A系统需要调用B,C,D三个系统串行处理,则处理的时间是所有系统处理时间的总和,例如商品下单时需要经过支付、库存、订单系统处理
引入MQ之后,A系统在发起下单请求时只需要将请求数据发送到MQ中,然后直接返回响应给用户,最后再由BCD系统去消费下单的消息,这样用户感受到的处理时间是A系统的处理时间。
3、消锋
流量解决的问题:
假设一个系统平常的流量只有1万tps,在搞活动的时候流量高峰则是10万tps,按照成本考量企业设计系统时不会按照10万tps要求,但是有时候有需要支持10万tps怎么办呢?解决方法就是加入一个MQ,在搞活动时当有10万请求时,请求数据会被放到MQ中,A系统批量取出数据进行处理,如果系统的处理能力是每秒2万,则只需5秒钟就可以处理完所有数据,这样就不会出现10万tps同时需要处理给到系统处理造成系统或数据超出负载而崩溃的问题。
二、MQ带来的问题以及解决方法
1、系统复杂性提高,可用性降低
系统多了一个组件就需要考虑MQ自身会不会出问题,万一MQ自己挂了会导致整个系统不可用。系统每多加一个组件都会导致系统的复杂性提高。
2、数据的一致性问题
系统异步第调用ABC三个系统完成下单当有一个服务处理失败时,如何保证数据的一致性
解决方法:采用分布式事务
3、MQ的常见问题解决方法
- 如何提高可靠性?
解决方法:搭建MQ镜像集群
- 如何保证消息不丢失?
解决方法:每次发送消息到MQ之后,MQ处理完通知发送方数据处理情况,例如消息生产方发送消息后如果再规定时间内没有收到回复就会重新发送消息。
- 如何保证消息不重复消费?
解决方法:在消息中添加一个唯一ID,消费端每次从MQ中取出消息都去查询一下是否已经存在,如果存在就丢弃。
- 如何保证消息传递的顺序?
例如一笔订单产生三条消息,分别是创建订单,支付、库存扣减,消费时需要按顺序依次消费
解决方法:让一笔订单中三条消息发送给同一个队列,消费时每取出一条消息就给队列加上分段锁,直到处理完第一个消息后释放锁
三、MQ不适用场景
如果用户的请求需要返回所有依赖系统处理后的数据就不能通过MQ来处理,例如用户注册。
四、MQ测试关注点
-
消息生产者测试
1、消息是否正确推送到预期队列中
2、消息是否推送到正确的topic下
3、重复发送同一条消息是否被接收
4、消息发送数量超过队列总长度是数据的处理方法
5、消息推送到每个topic下的queue如何分布
-
消息消费者测试
1、消费者消费模式是否与预期相符
2、消费者是否从预期队列中消费数据
3、消费者设定的topic的消费队列策略
4、消息被消费后是否被及时删除(看是否允许重复消费)
5、消费消息数量赶不上消息生产速度情况
6、pull与push消费类型测试
-
消息持久性测试
1、不同MQ对消息的持久化方式不一样
-
可靠性测试
1、Broker正常关闭
2、订阅与广播消息的消费是否符合预期
3、集群中任何一个节点故障情况
五、常用的MQ产品特点
| 特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
|---|---|---|---|---|
| 单机吞吐量 | 万级,吞吐量比RocketMQ和Kafka要低一个数量级 | 万级,吞吐量比RocketMQ和Kafka要低一个数量级 | 10万级,RocketMQ也是可以支撑高吞吐的一种MQ | 10万级1这是kafka最大的优点,就是吞吐量高。一般配置和数据类的系统进行实时数据计算、日志采集等场景 |
| 时效性 | ms级 | 微妙级,这是RabbitMQ的一大特点,就是延迟最低 | ms级 | 延迟在ms级内 |
| 可用性 | 基于主从架构实现高可用 | 高,基于主从架构实现高可用 | 非常高,分布式架构 | 非常高,kafka是分布式的,一个数据多个副本,少数机器宕机后,不会丢失数据,不会导致不可用 |
| 消息可靠性 | 有较低的概率丢失数据 | 消息不丢失 | 经过参数优化配置,可以做到0丢失 | 经过参数优化配置可以做到0丢失 |
| 核心特点 | MQ领域的功能及其完备 | 基于Erlang开发,所以并发能力强,性能及其好,延时很低 | MQ功能较为完善,还是分布式的,扩展性好 | 功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是实时上的标准。 |
| 非常成熟,功能强大,在业内大量公司以及项目都有应用。 但是偶尔消息丢失的概率,并且现在社区以及国内应用都越来越少,官方社区对ActiveMQ5.X维护越来越少,而且确实主要是基于解耦和异步来用的,较少在大规模吞吐场景中使用 | erlang语言开发的,性能及其好,延时很低。而且开源的版本,就提供的管理界面非常棒,在国内一些互联网公司近几年用RabbitMQ也是比较多一些,特别适用于中小型的公司 缺点显而易见,就是吞吐量会低一些,这是因为它做的实现机制比较中,因为使用erlang开发,目前没有多少公司使用其开发。所以针对源码界别的定制,非常困难,因此公司的掌控非常弱,只能依赖于开源社区的维护。 | 接口简单易用,毕竟在阿里大规模应用过,有阿里平台保障,日处理消息上 百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性都是OK的,还可以支撑大规模的topic数量,支持复杂MQ业务场景。 | 仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级别的延迟,极高的可用性以及可靠性,分布式可以任意扩展。 同时kafka最好是支撑较少的topic数量即可,保证其超高的吞吐量。 |
欢迎大家关注我的订阅号,会定期分享一些关于软件测试相关的文章,有问题也欢迎一起讨论学习!