盘点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
猜你喜欢
- 在对类访问使用时,常用到的有访问类的成员、方法。实例化在对类进行访问时,需要将类进行实例化。并产生一个对象。可以使用关键字new来实现。由于
- java Hibernate多对多映射前言:一、单向多对多 单向多对多的例子用人和职位来举例,一个人可以有多个职位
- C#串口模块的使用。使用VS .net框架下WinForm程序应用开发。C#开发的串口通信小工具。相比于QT添加的串口类,WinForm是通
- 目录1.引用Nuget包 ServiceStack.Redis2. string 类型的使用作
- spring Boot 熟悉后,集成一个外部扩展是一件很容易的事,集成Redis也很简单,看下面步骤配置:一、添加pom依赖
- 显示当前运行java代码的运行时的各种参数。不带显String操作。package systeminfo;import java.util.
- 本文实例讲述了C#实现获取程序路径方法。分享给大家供大家参考。具体如下:获取DLL的目录:Assembly myAssembly = Ass
- 一、前言字符串是多个字符连接起来组合成的字符序列。字符串分为可变的字符串和不可变的字符串两种。(1)不可变的字符串:当字符串对象创建完毕之后
- null与voidnull值用来表示数据类型未被赋予任何值,它是一种引用类型;void表示没有类型,或者说是没有任何值。null与void的
- 1、注解(Annotation)1.1 什么是注解(Annotation)注解不是程序本身,可以在程序编译、类加载和运行时被读取,并执行相应
- 很多时候,我们需要使用C#中的WebClient 来收发数据,WebClient 类提供向 URI 标识的任何本地、Intranet 或 I
- public class Count { public static void main(String[] args) { int i =
- 类锁和对象锁是否会冲突?对象锁和私有锁是否会冲突?通过实例来进行说明。一、相关约定为了明确后文的描述,先对本文涉及到的锁的相关定义作如下约定
- 补充使用Spring Cloud Config加密功能需要下载JCE扩展,用于生成无限长度的密文。链接:http://www.oracle.
- 1、设置ssh安装ssh相关软件包:sudo apt-get install openssh-client openssh-server然后
- 本文实例讲述了C#实现农历日历的方法。分享给大家供大家参考。具体实现方法如下://天干 private static
- 目前为止,我遇到使用Tomcat有三种情况:第一,使用Eclipse,在Eclipse中配置Tomcat。第二,直接在Tomcat中部署项目
- 配置文件context-path的坑context-path: /manage 这个配置加入后会导致访问spring的页面都需要加这个/ma
- 一、简单介绍翻看Spring的源码时,发现@Bean注解的源码上标注了Since: 3.0,也就是说,@Bean注解是Spring从3.0版
- 1. 安装JDK解释: JDK是Java编写环境--开发环境注: 安装路径不可出现中文及标点符号。比如:D:\Java\jdk81.1 下载