盘点MQ中的异常测试

目录
  • 前言
  • 一、RocketMQ 消息模式
    • 集群消费模式
    • 广播消费模式
  • 二、push 和 pull 优缺点
    • Pull方式
    • Push方式
    • 三、刷盘策略
      • 同步刷盘
      • 异步刷盘
  • 四、MQ 异常测试
    • MQ消息体
    • 消息重复发送
    • 消息到达顺序不一致
    • 消息发送失败重试
    • 接线上生产者
    • 消息丢失
    • 消息争用
    • MQ比落库快

前言

上一篇小结了一下关于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快,后来改成异步了。

以上就是盘点MQ中的异常测试的详细内容,更多关于MQ异常测试的资料请关注我们其它相关文章!

(0)

相关推荐

  • SpringBoot集成RabbitMQ和概念介绍

    目录 一.RabbitMQ介绍 二.相关概念 三.简单使用 1.配置pom包 2.配置文件 3.队列配置 4.发送者 5.接收者 6.测试 四.高级使用 1.Topic Exchange 2.Fanout Exchange 一.RabbitMQ介绍 RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性. 高可用性等方面表现不俗.RabbitMQ主要是为了实现系统之间的双向解耦而实现的.当生产者大量产生数据时,消

  • SpringBoot+RabbitMQ实现消息可靠传输详解

    目录 环境配置 消息丢失分析 生产阶段 生产端模拟消息丢失 RabbitMQ 消费端 环境配置 SpringBoot 整合 RabbitMQ 实现消息的发送. 1.添加 maven 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <depen

  • 详解SpringBoot整合RabbitMQ如何实现消息确认

    目录 简介 生产者消息确认 介绍 流程 配置 ConfirmCallback ReturnCallback 注册ConfirmCallback和ReturnCallback 消费者消息确认 介绍 手动确认三种方式 简介 本文介绍SpringBoot整合RabbitMQ如何进行消息的确认. 生产者消息确认 介绍 发送消息确认:用来确认消息从 producer发送到 broker 然后broker 的 exchange 到 queue过程中,消息是否成功投递. 如果消息和队列是可持久化的,那么确认消

  • MQ的分类组成优缺点测试点入门教程

    目录 一.什么是 MQ 二.MQ 的作用 1. 流量削峰 2. 应用解耦 3. 异步处理 三.MQ 的缺点 四.常见 MQ 分类 1. ActiveMQ 2. Kafka 3. RocketMQ 4. RabbitMQ 五.MQ 的组成 1. 角色 Broker:消息服务器,提供消息核心服务Producer:消息生产者,业务的发起方,负责生产消息传输给broker.Consumer:消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理.Topic:主题,发布订阅模式下的消息统一

  • MQ的消息模型及在工作上应用场景

    目录 MQ介绍 使用 MQ 的好处 使用 MQ 的坏处 什么时候用 MQ 消息模型 什么是 JMS 为什么需要 JMS 点对点模型 发布订阅模型 两个模型之间的区别 MQ 的在工作上应用场景 异步 使用 MQ 「MQ 带来的问题」 「MQ 产品的对比」 「MQ 的测试点」 » 生产者 » 消费者 队列 小结 MQ介绍 根据某科的介绍,MQ(message queue),叫消息队列,是基础数据结构中先进先出的一种数据机构. 一般用来解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩

  • 盘点MQ中的异常测试

    目录 前言 一.RocketMQ 消息模式 集群消费模式 广播消费模式 二.push 和 pull 优缺点 Pull方式 Push方式 三.刷盘策略 同步刷盘 异步刷盘 四.MQ 异常测试 MQ消息体 消息重复发送 消息到达顺序不一致 消息发送失败重试 接线上生产者 消息丢失 消息争用 MQ比落库快 前言 上一篇小结了一下关于redis的异常测试,今天再来盘一盘 MQ 相关的. MQ 跟 redis 一样,也是现在系统服务中不可或缺的重要中间件,通常用来流量削峰.应用解耦.异步处理等. 之前有过

  • Java中的异常测试框架JUnit使用上手指南

    JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework).Junit测试是程序员测试,即白盒测试.该项目主页:http://www.junit.org/ 使用JUnit时,主要都是通过继承TestCase类别来撰写测试用例,使用testXXX()名称来撰写单元测试. 用JUnit写测试真正所需要的就三件事: 1.  一个import语句引入所有junit.framework.*下的类. 2.  一个exte

  • Redis异常测试盘点分析

    目录 Redis测试中的异常 一.更新 Key 异常 二.Key的删除和丢失 三.KEY 过期策略不当造成内存泄漏 四.查询Redis异常时处理 五.redis 穿透.击穿.雪崩 六.Redis死锁 SET Key UniqId Seconds 分布式Redis锁:Redlock 七.Redis持久化 八.缓存与数据库双写时的数据一致性 Redis测试中的异常 在测试工作中,涉及到与 redis 交互的场景变的越来越多了.关于redis本身就不作赘述了,网上随便搜,本人也做过一些整理. 今天只来

  • 盘点Java中延时任务的多种实现方式

    目录 场景描述 实现方式 一.挂起线程 二.ScheduledExecutorService 延迟任务线程池 三.DelayQueue(延时队列) 四.Redis-为key指定超时时长,并监听失效key 五.时间轮 六.消息队列-延迟队列 场景描述 ①需要实现一个定时发布系统通告的功能,如何实现? ②支付超时,订单自动取消,如何实现? 实现方式 一.挂起线程 推荐指数:★★☆ 优点: JDK原生(JUC包下)支持,无需引入新的依赖: 缺点: (1)基于内存,应用重启(或宕机)会导致任务丢失 (2

  • SpringBoot中定制异常页面的实现方法

    定制异常页面,可以避免用户产生恐慌心理,使得产品有更好的用户体验.今天来学习在 SpringBoot 中如何定制开发异常页面 一.历史回顾 在 SpringMVC 年代,我们的异常页面一般配置在 web.xml 文件中,如下: <!-- 配置404页面 --> <error-page> <error-code>404</error-code> <location>/error/404.html</location> </erro

  • 详解c++中的异常

    一.什么是异常处理 一句话:异常处理就是处理程序中的错误. 二.为什么需要异常处理,异常处理的基本思想 C++之父Bjarne Stroustrup在<The C++ Programming Language>中讲到:一个库的作者可以检测出发生了运行时错误,但一般不知道怎样去处理它们(因为和用户具体的应用有关):另一方面,库的用户知道怎样处理这些错误,但却无法检查它们何时发生(如果能检测,就可以再用户的代码里处理了,不用留给库去发现). Bjarne Stroustrup说:提供异常的基本目的

  • Python中的异常类型及处理方式示例详解

    目录 前言 正文 一.什么是异常 二.异常的类型 三.异常处理 四.try 介绍 五.finally 介绍 六.raise 介绍 结尾 前言 Python 是一种面向对象的.解释型的.通用的.开源的脚本编程语言.现在市面上 Python 非常的流行,主要是因为它简单易用,学习成本低,比如要实现某个功能,Python 可能只需要几行代码,而用C语言可能需要上百行代码,因为C语言什么都要得从头开始编码,而 Python 已经内置了很多功能模块,所以,我们只需要导入特定的包,就可以实现想要的效果. 正

  • 详解Java中多线程异常捕获Runnable的实现

    详解Java中多线程异常捕获Runnable的实现 1.背景: Java 多线程异常不向主线程抛,自己处理,外部捕获不了异常.所以要实现主线程对子线程异常的捕获. 2.工具: 实现Runnable接口的LayerInitTask类,ThreadException类,线程安全的Vector 3.思路: 向LayerInitTask中传入Vector,记录异常情况,外部遍历,判断,抛出异常. 4.代码: package step5.exception; import java.util.Vector

  • Java中内存异常StackOverflowError与OutOfMemoryError详解

     Java中内存异常StackOverflowError与OutOfMemoryError详解 使用Java开发,经常回遇到内存异常的情况,而StackOverflowError和OutOfMemoryError便是最常遇见的错误. 首先,看看这两种错误的解释: 如果当前线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常. 如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常. 这里把异常分为两种情况,但是存在一些相互重

  • 深入探讨JAVA中的异常与错误处理

    异常与错误: 异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发人员)已经犯了个错误,现在有一个机会来修改它.Java中使用异常类来表示异常,不同的异常类代表了不同的异常.但是在Java中所有的异常都有一个基类,叫做Exception. 错误: 它指的是一个合理的应用程序不能截获的严重的问题.大多数都是反常的情况.错误是VM的一个故障(虽然它可以是任何系统级的服务).

随机推荐