消息中间件中常见问题

news2024/7/6 17:51:19

在这里插入图片描述

如何保证消息不丢失

MQ的用途

  • 异步发送(验证码,短信,邮件)
  • MySQL,ES,Redis之间的数据同步
  • 分布式事务
  • 削峰填谷
    在这里插入图片描述

消息可能丢失的环境

  • 消息在产生端时候生产端挂掉,消息未到达交换机,消息丢失
  • 消息在交换机未到达队列,消息丢失
  • 消息队列中如果队列挂掉消息也可能丢失
  • 消费者未接收消息,消息也可能丢失

针对消息丢失的解决方案:
生产者确认机制
RabbitMQ提供了 publisher confirm 机制来避免消息发送到MQ的过程中丢失,消息发送到MQ之后,会返回一个结果给发送者,表示消息发送是否处理成功。
在这里插入图片描述
如果发到交换机失败会返回一个nack publish-confirm
如果发送到消息队列失败会返回ack publish-return

消息发送失败的处理方式

  • 回调方法即可重发
  • 记录日志
  • 保存到数据库然后定时发送,发送成功后即可删除表中的数据

消息持久化
MQ默认是内存存储消息,开启内存持久化功能可以确保缓存在MQ中的消息不丢失。
在这里插入图片描述
消息确认
RabbitMQ支持消费者确认机制,即:消费者处理消息后可以向MQ返回ack回执,MQ收到ack回执之后才会删除该消息

  • 而SpringAMQP则允许配置三种确认机制:
    • manual:手动ack,需要业务代码结束之后,调用api发送ack
    • auto:自动ack,有Spring监测listener代码是否出现异常,没有响应则返回ack,抛出异常则返回nack
    • none:关闭ack,MQ假定在获取消息后会成功处理,因此消息投递后立即被删除

我们可以利用Spring的retry机制,在消费者出现异常的时候利用本地重试,设置重试次数,当重试次数到了多少之后,如果消息依然失败,将消息投递带异常的交换机,交由人工处理。

在这里插入图片描述
RabbitMQ-如何保证消息不丢失?

  • 开启生产者确认机制,确保生产者的消息能到达队列中
  • 开启持久化功能,确保消息未消费钱在消息队列中不能丢失
  • 开启消费确认机制未Auto,由Spring确认消息处理成功后完成ack
  • 开启消费者失败重试机制,多次重试失败后将消息投递到异常交换机,交由人工处理

RabbitMQ消息重复消费问题

可能出现重复消费的原因:

  • 网络抖动
  • 消费者挂了

在这里插入图片描述
解决方案:(适用于任何MQ)

  • 给每条消息设置唯一的标识id
  • 幂等方案:【分布式锁,数据库锁(悲观锁,乐观锁)】

RabbitMQ中死信交换机

**问题:**RabbitMQ死信交换机?RabbitMQ延迟队列有了解过嘛?

  • 延迟队列:进入队列的消息会被延迟消费的队列
  • 场景:超时订单,限时优惠,定时发布
    在这里插入图片描述
    延迟队列=死信交换机+TTL(生存时间)

死信交换机
当一个队列中的消息满足下列情况之一时,可以被称为死信(dead letter)

  • 消费者使用basic.reject或者basic.nack声明消费失败,并且将参数requence参数设置为false
  • 消息是一个过期的消息,超时无人消费
  • 要投递的队列消息堆积满了,最早的消息可能成为死信

如果该队列配置了dead-letter-exchange属性,执行了交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机被称为死信交换机(Dead Letter Exchange,简称DLX)
在这里插入图片描述
TTL
TTL,也就是Time-To-Live。如果一个队列中的消息TTL结束仍未消费,则会变成死信,TTL超时分为两种情况:

  • 消息所在的队列设置了存活时间
  • 消息本身设置了存活时间

在这里插入图片描述
setExpiration(“5000”)表示消息存活的时间

延迟队列插件

DelayExchange插件,需要安装在RabbitMQ中

RabbitMQ有一个官方的插件社区,地址为:https://www.rabbitmq.com/community-plugins.html
在这里插入图片描述
延迟队列的插件

DelayExchange的本质还是官方的三种交换机,只是添加了延迟的功能,因此使用时需要声明一下交换机,交换机类型可以是任意的类型,然后设定delayed属性为true即可。

在这里插入图片描述

RabbitMQ中的死信交换机?(RabbitMQ延迟队列有了解过吗?)

  • 我们当时一个业务使用到了延迟队列(超时订单,限时优惠,定时发布)
  • 其中延迟队列就是用到了死信交换机和TTL(消息存活时间)实现的
  • 消息超时未消费就变成了死信(死信的其他情况:拒绝消费,队列满了)

延迟队列插件实现延迟队列DelayExchange

  • 声明一个交换机,添加delayed属性为true
  • 发送消息时,添加x-delay头,值为超时时间

RabbitMQ消息堆积

RabbitMQ如果有100万消息堆积在MQ,如何解决(消息堆积怎么解决)
当生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,指导队列存储消息达到上限,之后发送的消息就会成为死信,可能会被丢弃,这就是消息堆积问题。
在这里插入图片描述
解决的方式:

  • 添加更多的消费者,提高消费速度
  • 在消费者内开启线程池加快消息处理速度
  • 扩大队列容积,提高堆积上限

惰性队列

  • 接收消息后直接存储在磁盘中并非内存中
  • 消费者要消费消息是才会从磁盘中读取到内存中
  • 支持百万条消息存储
    在这里插入图片描述
    RabbitMQ如果有100万消息堆积在MQ,如何解决(消息堆积怎么解决)

解决消息队列的三种思路:

  • 增加更多的消费者,提高消费的速度
  • 在消费者内开启线程池加快消息处理的速度
  • 扩大队列容积,提高堆积的上限,采用惰性队列
    • 在声明队列的时候可以设置属性x-queue-mode为lazy,即为惰性队列
    • 基于磁盘存储,消息上限高
    • 性能比较稳定,但基于磁盘存储,受限与磁盘的IO,时效性降低

RabbitMQ高可用性

  • 在生产环境下,使用集群来保证高可用性
  • 普通集群,镜像集群,仲裁集群

普通集群

普通集群,或者交标准集群(classic cluster),具备以下特征:

  • 会在集群的各个节点共享部分数据,包括:交换机,队列元信息。不包括队列中的消息。

  • 当访问集群中的某个节点的时候,如果队列不在该节点,会从数据所在的节点传递到该节点并返回

  • 队列所在的节点宕机,队列中的消息就会丢失

在这里插入图片描述

如果有一个消费者需要访问其中一个节点,而这个节点恰好宕机了,那么消息就会丢失

因此不能做到高可用。

镜像模式

镜像集群:本质是主从模式,具备以下的特征:

  • 交换机,队列,队列中的消息会在各个MQ的镜像节点之间同步备份
  • 创建队列的节点被称为该队列的主节点,备份到其他节点叫做该队列的镜像节点
  • 一个队列的主机诶带你可能是另一个队列的镜像节点
  • 所有的操作都是主节点完成,然后同步到镜像节点
  • 主节点宕机后,镜像节点会替代新的主节点
    在这里插入图片描述
    仲裁队列

仲裁队列:是在3.8之后才有的新功能,用来替代镜像队列,具有下列的特征:

  • 与镜像队列一样,都是主从模式,支持主从数据同步

  • 使用非常简单,没有复杂的配置

  • 主从同步基于Raft协议,强一致性
    在这里插入图片描述
    RabbitMQ的高可用性机制有了解过吗?

  • 生产环境下,我们主要采用的镜像模式搭建的集群,共有3个节点

  • 镜像队列结构式一主多从(从就是就是镜像),所有的操作都是主节点完成的,完后同步给镜像节点

  • 主节点宕机后,镜像节点会替代成新的主节点(如果在主节点同步完成前,主已经宕机了,可能会出现数据丢失的问题)

数据丢失的问题如何解决?

  • 我们可以采用仲裁队列,与镜像队列一样,都是主从模式,支持主从数据同步,主从同步基于Raft协议,强一致性,并且使用起来也非常简单,不需要额外的配置,在声明队列的时候只要指定这个是仲裁队列即可

KafKa如何保证消息不丢失

Kafka如何保证消息不丢失
使用Kafka在消息收发的过程中都会出现消息丢失,Kafka分别给出了解决方案

  • 生产者发送消息到Broker丢失
  • 消息在Broker中存储丢失
  • 消费者从Broker接收消息丢失
    在这里插入图片描述

生产者发送消息到Broker丢失

  • 设置异步发送(同步发送会导致线程阻塞)
    在这里插入图片描述
    消息发送失败的话记录日志
  • 采用消息重试机制
    在这里插入图片描述
    消息在Broker中存储丢失
    在这里插入图片描述
  • 发送确认机制acks
确认机制说明
acks=0生产者在成功写入消息之前不会等待任何来自服务器的响应,消息有丢失的风险,但是速度最快
acks=1(默认值)只要集群首领节点收到消息,生产者就会收到一个来自服务器的成功响应
acks=all只要当所有参与赋值的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应

消费者从Broker接收消息丢失
在这里插入图片描述

  • Kafka中的分区机制指的就是将每个主题划分成多个分区(Partition)
  • Topic分区中消息只能由消费者组中的唯一一个消费者处理,不同的分区分配给不同的消费者(同一个消费者组)
    不同的分区都是按照偏移量来存储数据的
    在这里插入图片描述
    并且消费者在消费之后会设置消费者自动提交偏移量,默认5秒一次,那么如果出现了重平衡的情况下,可能会造成重复消费和丢失数据问题。
    在这里插入图片描述
    如果消费者3负责p3队列的消费者,当消费者消费到6的时候消费者还没来得及提交偏移量,消费者挂了,那么系统会分配到别的消费者根据偏移量进行消费,那么就会出现问题,分配过来的消费者1就会从4开始消费,那么就会出现重复消费的问题。

解决方案:

  • 禁止自动提交偏移量,改为手动提交

  • 同步提交

  • 异步提交

  • 同步+异步组合提交
    在这里插入图片描述
    Kafka如何保证消息不丢失?
    需要从以下的三个方面去解决这个问题:

  • 生产者发送消息到Broker丢失

    • 设置异步发送,发送失败使用回调进行记录和重发
    • 失败重试,参数配置,可以设置重试次数
  • 消息在Broker中存储丢失

    • 发送acks,选择all,让所有的副本都保存数据之后确认
  • 消费者从Broker中接收消息丢失

    • 关闭自动提交偏移量,开启手动提交偏移量
    • 提交方式,最好是同步+异步提交
      Kafka中消息的重复消费问题如何解决?
  • 关闭自动提交偏移量,开启手动提交偏移量

  • 提交方式,最好是同步+异步

  • 幂等方案

Kafka如何保证消息顺序性

应用场景:

  • 即时消息中的单对单聊天和群聊,保证消息发送方消息发送和接受方的顺序一致性
  • 充值转账两个渠道在同一时间进行余额变更,短信通知必须要顺序
    在这里插入图片描述
    Topic分区中消息只能由消费者组中的唯一一个消费者处理,所以消息肯定是按照先后顺序进行处理的,但是它也仅仅是保证Topic的一个分区顺序处理,不能保证跨分区的消息先后处理顺序,所以如果你想要顺序处理Topic的所有消息,那就只提供一个分区。
    在这里插入图片描述
    Kafka如何保证消费的顺序性?
    问题原因:
    一个Topic的数据可能存储在不同的分区中,每个分区都有一个按照顺序的存储的偏移量,如果消费者关联了多个分区不能保证顺序性。
    解决方案:
  • 发送消息时制定分区号
  • 发送消息时按照相同的业务设置相同的key

Kafka高可用机制

Kafka的高可用机制了解吗?
在这里插入图片描述

  • Kafka的服务端被称为Broker的服务进行构成,即一个Kafka集群由多个Broker组成
  • 这样如果集群中某一台机器宕机,其他的机器上的Broker也依然能够对外提供服务,这其实就是Kafka提供的高可用的手段之一
    分区备份机制
    在这里插入图片描述
    假设某一个topic中有三个分区p0,p1,p2
  • 一个Topic中有多个分区,每个分区有多个副本,其中一个是leader,其他的都是flower,副本存储在不同的Broker中
  • 所有的分区副本的内容都是相同的,如果发生leader发生故障的时候,会自动将其中的一个follower提升为leader

分区备份机制
在这里插入图片描述
ISR(in-sync replica)需要同步复制保存的follower
如果leader失效后,需要选取新的leader,选举原则如下:
第一:选举是有限从ISR中选定,因为这个列表中follower的数据时与leader同步的
第二:如果ISR列表中follower都不行,就只能从其他follower中选取
在这里插入图片描述
Kafka的高可用性机制了解过吗?
可以从两个层面回答,第一是集群,第二个是复制
集群:
一个Kafka集群由多个Broker实例组成,即时某一台宕机,也不能耽误其他Broker继续对外提供服务
复制机制:

  • 一个Topic由多个分区,每个分区有多个副本,有一个leader,其余都是follower,副本存储在不同的Broker
  • 所有的分区副本的内容都是相同的,如果leader发生故障时,会自动将其中follower提升为leader,保证系统的容错性,高可用性。

解释一下复制机制中的ISR
ISR(in-sync replica)需要同步复制保存的follower

分区副本分为两类,一个ISR,与leader副本同步保存数据,另外一个普通副本,是异步同步数据,当leader挂掉之后,会优先从ISR副本列表中选取一个作为leader。

Kafka数据清理机制

  • Kafka文件存储机制
  • Kafka数据清理机制

Kafka文件存储机制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-svasRlbJ-1687243093845)(assets/image-20230523151425403.png)]

Kafka采用了分段存储的方式存储数据

为什么采用分段呢?

  • 删除无用的文件更加方便,提高磁盘利用率
  • 查找数据更便捷

默认7天清理一次

数据清理机制

日志清理策略有两个

  1. 根据消息的保留时间,当消息在Kafka中保存的时间超过了指定的时间,就会触发清理程序,默认7天
    在这里插入图片描述

  2. 根据topic存储的数据大小,当topic所占的日志文件大小大于一定的阈值,则开始删除最久的消息,需手动开启

在这里插入图片描述

Kafka数据清理机制了解过吗?

Kafka存储结构

  • Kafka中topic的数据存储在分区上,分区如果文件过大会分段存储segment
  • 每个分段都在磁盘上以索引(xxxx.index)和日志文件(xxxx.log)的形式存储
  • 分段的好处是,第一能够尖山单个文件内容的大小,查找数据方便,第二方便Kafka进行日志清理

日志清理的策略有两个:

  • 根据消息的保留时间,当消息保存时间超过了指定的时间,就会触发清理,默认是168小时(7天)
  • 根据topic存储数据大小,当topic所占的日志文件大小大于一定的阈值,则开始删除最久的消息。(默认关闭)

Kafka高性能设计

Kafka的高性能设计了解过吗?

  • 消息分区:不受单台服务器的限制,可以不受限制的处理更多的数据
  • 顺序读写:磁盘顺序读写,提高读写性能
  • 页缓存:把磁盘中的数据缓存到内存中,把从磁盘的访问变为对内存的访问
  • 零拷贝:减少上下文切换及数据拷贝
  • 消息压缩:减少磁盘IO和网络IO
  • 分批发送:将消息打包批量发送,减少网络开销

零拷贝

Linux中传统Kafka的数据消费的方式(一共要经过4次拷贝性能并不高)

在这里插入图片描述

零拷贝技术:
在这里插入图片描述

当确定消费者之后直接将任务委托给Linux系统进行操作,这样只拷贝了两次

Kafka中实现高性能的设计了解过吗?

  • 消息分区:不受单台服务器的限制,可以不受限制的处理更多的数据
  • 顺序读写:磁盘顺序读写,提高读写的效率
  • 页缓存:把磁盘中的数据缓存到内存中,把对磁盘的访问变为对内存的访问
  • 零拷贝:减少磁盘IO和网络IO
  • 分批发送:将消息打包批量发送,减少网络开销

笔记是对黑马课程中的知识进行的个人总结,图片借鉴了课程视频中的资料,感谢黑马程序员的开源精神,哈哈,如有问题联系我删除!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/666491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【新车评分】降价三万,排名第一的蔚来ES7更能打了?

去年6月,蔚来上市了该品牌第四款SUV车型——ES7,共分为两个版本标准版和首发版,发售价分别为46.8万和54.8万元。 不过近期蔚来以砍掉部分车主权益,换来了全系车型3万元的降价,ES7的起售价也来到了43.8万元和51.8万元。…

【Python 随练】利用递归方法求 5!

题目 利用递归方法求 5!。 简介 在本篇博客中,我们将使用递归方法解决一个数学问题:计算一个数的阶乘。阶乘是指将从1到某个正整数n的所有整数相乘,通常表示为n!。我们将介绍递归的概念,并给出一个完整的代码示例来计算给定数的…

P-Tuning v2: 与微调性能相等的提示性优化

原文:P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks 作者: Xiao Liu1,2 , Kaixuan Ji1 代码: https://github.com/THUDM/P-tuning-v2 一、简介 二、准备工作 ---- 2.1 NLU的任务 ---- 2.2 提示优化 三、P-Tu…

什么是云原生?

目录 1.简介2.云元素的四要素 1.简介 云原生:是一种构建和运行应用程序的方法,是一套技术体系和方法论。云原生(CloudNative)是一个组合词,Cloud Native: Cloud 表示应用程序位于云中,而不是…

基于OpenMV 循迹小车 + WIFI无线图传

文章目录 一、工程环境二、OpenMV1. 色块选定2. 色块识别3. 串口通信4. WiFi无线图传5. 代码汇总 三、MSP430四、视频演示 一、工程环境 1. 软件 OpenMV IDECode Composer StudioMicrosoft Edge 2. 硬件 MSP430F5529OpenMV4 H7及其 WiFi拓展板视觉云台旋转编码器、oled显示…

国际原油期货怎么开户?国际原油期货开户流程是什么?

随着国际原油期货交易的大众化,国际原油期货交易的入市门槛也在逐渐降低,使越来越多的国际原油期货交易爱好者能够参与到这个交易市场中。很多朋友可能对国际原油期货开户有很多的疑问,是不是很繁琐?需不需要很多的证明文件&#…

论文解读 | 皮质电图系统与软机器人致动器的完美结合

原创 | 文 BFT机器人 01 研究内容 主要研究内容是关于一种电皮层图谱系统的部署,该系统使用软体机器人致动器。论文详细介绍了该系统的制造和实验方法,并提供了相关的图表和参考文献。该系统的设计旨在提高电皮层图谱系统的灵活性和可植入性&#xff0c…

vite+vue3+cesium环境搭建

1.创建一个Vite项目 npm create vitelatest 2.安装cesium插件:vite-plugin-cesium npm i cesium vite-plugin-cesium vite -D 3、配置vite.config.js import cesium from vite-plugin-cesium; export default defineConfig({ plugins: [vue(),cesium()] }) 4、清空…

软件测试技能,JMeter压力测试教程(二)

目录 前言 一、案例场景 二、登录请求 三、Json 提取器 四、关联请求 五、遇到的坑 前言 现在很多接口的登录是返回一个json数据,token值在返回的json里面,在jmeter里面也可以直接提取json里面的值 上一个接口返回的token作为下个接口的入参 一、…

Python基础(12)——Python字符串详解

Python基础(12)——Python字符串详解 文章目录 Python基础(12)——Python字符串详解课程:字符串目标一. 认识字符串1.1 字符串特征1.2 字符串输出1.3 字符串输入 二、下标2.1 快速体验 三、切片3.1 语法3.2 体验 四、常…

Generative Adversarial Network(生成对抗网络)

目录 Generative Adversarial Network(生成对抗网络) Basic Idea of GAN GAN as structured learning Can Generator learn by itself Can Discriminator generate Theory behind GAN Conditional GAN Generative Adversarial Network(…

SpringBoot + Vue前后端分离项目实战 || 一:Vue前端设计

文章目录 环境配置开发工具下载Vue前端模板前端项目启动前端说明及修改修改导航栏自定义菜单与子菜单增加导航标签功能 前端数据格式 B站视频讲解:2023全网最简单但实用的SpringBootVue前后端分离项目实战 不想看视频可浏览此文章笔记,比较详细 环境配置…

民族工业领军企业:大族激光全流程数字化增长路径揭秘

1.关于大族激光 大族激光科技产业集团(简称“大族激光”,股票代码 002008)于 1996 年创立、2004 年上市,是亚洲最大、世界排名前三的工业激光加工及自动化整体解决方案服务商,专业从事工业激光加工设备与自动化等配套…

Python面向对象编程2-面向过程的银行账号模拟程序 项目2.2 取款与查看余额

项目总目标:用面向过程思想设计一个简单的银行账号模拟程序。本次将迭代多个程序版本,每个版本都将添加更多功能。虽然这些程序没有达到发布的质量标准,但整个项目的目的是关注于代码如何与一个或多个银行账户的数据进行交互。 分析项目的必要…

MySQL8漏洞处理之小版本升级至8.0.33

MySQL低版本经常会出现一些漏洞,有些高危漏洞就得处理,以防未知风险。 一、漏洞描述 MySQL 安全漏洞(CVE-2023-21912)(CVE-2023-21980): Oracle MySQL 5.7.41 版本及之前版本和 8.0.32 版本及之前版本的 Client programs 组件存在安全漏洞。低权限攻击…

使用Channel的一些业务场景

使用Channel的一些业务场景 首先需要明确的就是,发送方才知道什么时候关闭 channel ,这个是比较符合逻辑的。 我们需要知道哪些情况会使 channel 发生 panic 关闭一个 nil 值会引发关闭一个已经关闭的 channel 会引发向一个已经关闭的 channel 发送数据…

职场人的AI私塾,帮你打造得力的AI助手

你有没有想过,为什么有一些周围的小伙伴,工作量看着也不少,但事务处理速度特别快,质量也不差;一些看起来难度比较大或者生疏的工作,也能轻松应付得来,难道他们都是天生的工作能力出众&#xff1…

小白速看!带你轻松解决Java的空指针异常

关注“Java架构栈”微信公众号,回复暗号【Java面试题】即可获取大厂面试题 异常案例 对很多Java初学者来说,在学习的初期是很容易遇到各种异常的,就比如咱们今天要讲的这个空指针异常。所谓“授之以鱼,不如授之以渔”,…

Q-Vision+Kvaser CAN/CAN FD/LIN总线解决方案

智能联网技术在国内的发展势头迅猛,随着汽车智能化、网联化发展大潮的到来,智能网联汽车逐步成为汽车发展的主要趋势。越来越多整车厂诉求,希望可以提供本土的测量软件,特别是关于ADAS测试。对此,Softing中国推出的Q-V…

CppUnit——【由JUnit移植过来的】C++单元测试框架——的下载安装

C单元测试框架CppUnit的下载与安装 简介下载地址导入到Virtual Studio准备条件根据VS版本选择导入对应的.sln文件 简介 CppUnit是【由JUnit移植过来的】C测试框架。 下载地址 从我使用的CppUtest框架中的文档/readme/ReadmePart1_VisualStudio.rtf文件中看到了官网的地址cpp…