盘点MQ中的异常测试
作者:把苹果咬哭的测试笔记 发布时间:2022-05-06 07:39:24
前言
上一篇小结了一下关于redis的异常测试,今天再来盘一盘 MQ 相关的。
MQ 跟 redis 一样,也是现在系统服务中不可或缺的重要中间件,通常用来流量削峰、应用解耦、异步处理等。
之前有过一篇整理【MQ 快速入门】介绍、分类、组成、优缺点、测试点,有兴趣也可以跳过去看看。
日常经手的系统主要用的是 RocketMQ,是阿里系下开源的一款分布式、队列模型的消息中间件,是阿里参照kafka设计思想使用java实现的一套MQ,并做了自己的改进。被广泛的应用在订单、交易、充值、流计算、消息推送、日志流处理等场景。
这里再简述一些知识点。
一、RocketMQ 消息模式
RocketMQ中,也存在两种消息模式,分别为集群消费模式和广播消费模式。
集群消费模式
RocketMQ默认的消息模式就是集群模式,当存在多个消费者时,消息通过一定负载均衡策略,将消息分发到多个consumer中。
比如现在有3个消费者,那么一条消息投递过来,只会被consumer 1、consumer 2、consumer 3中的一个消费。
在RockeMQ中,通过ConsumeGroup的机制,实现了天然的消息负载均衡,可以非常方便的通过加机器来实现水平扩展。
广播消费模式
这种模式下,会把消息分发给每一个消费者。一条消息投递过来,会被 consumer 1、consumer 2、consumer 3都消费一次,就像发了条朋友圈,你的朋友都可以看见。
目前我们用的比较多的是集群模式,在集群模式也可以模拟广播消费。
二、push 和 pull 优缺点
对于任何一款消息中间件而言,消费者客户端一般有两种方式从消息中间件获取消息并消费。
Pull方式
由消费者客户端主动向消息中间件(MQ消息服务器代理)拉取消息。
适用场景:对于生产者生产消息数据比较大时,而消费端处理比较复杂,消费能力相对较低。
优点:消费者可以依据自己的消费能力进行消费,生产者不需要维护和消费者之间的会话。
缺点:拉取消息的间隔不太好设置。间隔太短,对服务器请求压力过大。间隔时间过长,那么必然会造成一部分数据的延迟,实时性相对较低。
优化方案:
长轮询的消费方式,需要Server和Client的配合才能够实现。
即Client发送消息请求,Server端接受请求,如果发现Server队列里没有新消息,Server端不立即返回,而是持有这个请求一段时间(通过设置超时时间来实现),在这段时间内轮询Server队列内是否有新的消息,如果有新消息,就利用现有的连接返回消息给消费者;如果这段时间内没有新消息进入队列,则返回空。
长轮询的弊端:在持有消费者请求的这段时间,占用了系统资源,因此长轮询适合客户端连接数可控的业务场景中。
Push方式
由消息服务端主动地将消息推送给消费者,尽可能实时地将消息发送给消费者进行消费。
适用场景:对于数据实时性要求高的场景。
优点:生产者主动推送给消费者,及时性很高。
缺点:当消费者消费能力远低于生产者生产能力,那么一旦生产者推送大量消息到消费者时,就会导致消费者消息堆积,处理缓慢,甚至服务崩溃。
另外,生产者需要维护和每个消费者之间的会话。
优化方案:不采用 http 长连接的方法保持会话,采用 socket 监听。
三、刷盘策略
RocketMQ的存储读写是基于JDK NIO的内存映射机制的,消息存储时首先将消息追加到内存中,再根据不同的刷盘策略在不同的时间进行刷盘。
同步刷盘
同步刷盘是指数据到达内存之后,必须刷到commitlog日志之后才算成功,然后返回producer数据已经发送成功。
异步刷盘
指数据到达内存之后,返回producer说数据已经发送成功,然后再写入commitlog日志。
什么是commitlog?
commitlog 就是来存储所有的元信息,包含消息体,类似于Mysql、Oracle 的 redolog。所以只要有 CommitLog 在,Consume Queue即使数据丢失,仍然可以恢复出来。
而 consumequeue,就是用来记录数据的位置,以便 Consumer 快速通过 consumequeue 找到 commitlog 中的数据。
四、MQ 异常测试
MQ消息体
MQ消息体中某些必填参数为 NULL,或者全部必填都为NULL,字段类型、长度是否不符合约定等。
消息重复发送
消息重复发送,只消费一条,一般根据消息内容中唯一标识来去重。
消息到达顺序不一致
消息到达顺序不一致,导致业务异常。
比如:订单下单后再取消,如果先收到取消的消息,再收到下单消息,就会有问题。
消息发送失败重试
Producer端重试
比如网络抖动导致生产者发送消息到MQ失败,可以手动设置发送失败重试的次数。
Consumer端重试
默认16次,重试时间间隔会越来越长,如果失败的多,容易堆积。这里的重试次数可自定义设置。
值得注意的是,只有消息推送失败才需要重推,不要把其他失败的情况也进行重试。
接线上生产者
接线上已有的生产者,需要注意,必须设置消费开始时间,不然上线时会大批量消息过来会造成堆积,可能造成故障。
消息丢失
消息丢失,业务是否兼容,是否有补偿或者监控机制。
消息争用
如果是集群模式,同一topic下新增新的消费组,但是没有申请新的group,导致一条消息投递过来,多个消费组争抢。
比如开发为了省事,预发和线上同一个topic,消费组的group也一样,上线后,可能存在有效消息被预发消费组消费了。
MQ比落库快
比如某接口A,新增一条数据后会同步更新DB和发送MQ给服务B,服务B收到消息后查询DB这条数据。曾经发现了收到消息却查不到数据的情况,因为数据库更新速度没有MQ快,后来改成异步了。
来源:https://www.cnblogs.com/pingguo-softwaretesting/p/15911770.html


猜你喜欢
- 本文实例讲述了C#实现Xml序列化与反序列化的方法。分享给大家供大家参考。具体实现方法如下:/// <summary>/// X
- 这几天恰好和朋友谈起了递归,忽然发现不少朋友对于“尾递归”的概念比较模糊,网上搜索一番也没有发现讲解地完整详细的资料,于是写了这么一篇文章,
- 1. 概述当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。2. 解决的问题主要解决的是当控制一个对象状态转换的条件表
- 本文实例为大家分享了jdk1.7配置教程,供大家参考,具体内容如下第一步:下载jdk1.7下载地址:链接 密码: wrmf第二步:
- 目录1 创建 xml 动画文件2 加载使用3 聊一聊 AnimationDrawable3.1 使用 ViewTreeObserver3.2
- java8的stream流能完美解对象集合去重问题. List<UserCar> list1 = new ArrayList()
- 双向信号和竞赛(Two-Way Signaling and Races) Monitor.Pulse方法的一个重要特性是它是异步执
- 本文实例为大家分享了Android自定义广播接收的具体代码,供大家参考,具体内容如下实现效果:MainActivity.java代码:pac
- 比如在类上使用该注解 @Alias("dDebtEntity")则在mapper.xml文件中resultType=&q
- Maven本地仓库有对应的jar包但是报找不到问题原因第一,你本地仓库对应的包文件夹下有_remote.repositories这个文件;第
- 本文实例为大家分享了Java实现图形界面计算器的具体代码,供大家参考,具体内容如下 代码:import javax.swing.*
- 1 前言在 Springboot 中,异步任务和定时任务是经常遇到的处理问题方式,为了能够用好这两项配置,不干扰正常的业务,需要对其进行异步
- 我自己在使用的过程中遇见的问题,百度找了很久才找到合适的方法。报错如下:Emulator: emulator: ERROR: Unknown
- 获取手机唯一标识 拼接的方式获取手机唯一标识第一种方式是获取IMEI,但是有的手机如果不是正品的话,就获取不到所以通过这一种方式还是会出现有
- 注解作用注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。它主要的作用有
- 开放端口安全组没开放端口是原罪!!!导致好多BUG费时费力。Hbase悄悄 * 的用了好多端口,比如被我抓到的42239,直接搜索报错药不对症
- 这篇文章主要介绍了spring cloud Ribbon用法及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学
- C#控制台程序使用Log4net日志组件,供大家参考,具体内容如下1、Log4net一般都不陌生,但是在配置上不同类型的项目又不相同的地方比
- 这篇文章主要介绍了Java使用Collections工具类对List集合进行排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一
- InputStreamReader 类1、概述转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流