【MQ】消息队列的简介以及常见问题的解决方案

news2024/11/17 1:33:17

MQ

MQ的基本概念

MQ全称Message Queue(消息队列),实在消息的传输过程中保存消息的容器。多用于分布式系统之间的通信。

分布式系统的两种通信方式:直接调用、借助第三方间接完成

发送者成为生产者,接受者称为消费者
在这里插入图片描述
MQ的优势和劣势

优势:

  1. 应用解耦:提高容错性和可维护性
  2. 异步提速:提升用户体验和系统吞吐量
  3. 削峰填谷:提高系统稳定性。比如说我平时服务就只能支撑几万的qps,像淘宝京东那种秒杀,那时候服务突然打进来那服务就会直接被压死了。但是如果采用消息队列,这秒杀进来的所有的请求都不会直接打到具体服务上,都会先打到消息队列里,然后我后面的服务再慢慢消费。

劣势:

  1. 系统可用性降低:如何保证高可用?
  2. 系统复杂性提高:如何保证消息没有被重复消费?怎么处理消息丢失?怎么保证消息传递的顺序性?
  3. 一致性问题:如何保证消息数据的一致性?

MQ常见的问题

  1. mq如何避免消息堆积问题。

    消息堆积:生产者的生产速率远远大于消费者的消费速率,使消息大批量的堆积在消息队列。

    解决方案:

    1. 提升消费者的消费速率(增加消费者集群)
    2. 消费者分批多线程去处理
    3. 限流,保证进入到消息队列的都是有用的消息
  2. 如何避免重复消费问题

    **产生原因: **

    1. 生产者产生了两条一模一样的消息。
    2. 消费者一条消息消费了多遍

    消息重试:消息重试一般发生于一个消费者发生了异常(网络波动或者系统假死),这个时候这个消费者就会通知生产者重新发送。就会带来重复消费的问题。

    可以采用常用的幂等解决方案(分布式锁),全局id+业务场景保证唯一性。所有的重复提交问题,都可以用幂等性来解决。

    为了保险起见,也可以在数据库上做好唯一索引。

  3. 如何保证消息不丢失

    1. 消息确认机制,生产者必须确认消息成功刷盘到硬盘中,才确认消息发送成功。

      acks 参数指定了必须要有多少个分区副本收到消息,生产者才会认为消息写入是成功的。这个参数对消息丢失的可能性有重要影响。该参数有如下选项。

      • 如果 acks=0 ,生产者在成功写入消息之前不会等待任何来自服务器的响应。也就是说,如果当中出现了问题,导致服务器没有收到消息,那么生产者就无从得知,消息也就丢失了。不过,因为生产者不需要等待服务器的响应,所以它可以以网络能够支持的最大速度发送消息,从而达到很高的吞吐量。

      • 如果 acks=1 ,只要集群的Leader节点收到消息,生产者就会收到一个来自服务器的成功响应。如果消息无法到达Leader节点(比如Leader节点崩溃,新的Leader还没有被选举出来),生产者会收到一个错误响应,为了避免数据丢失,生产者会重发消息。不过,如果一个没有收到消息的节点成为新Leader,消息还是会丢失。这个时候的吞吐量取决于使用的是同步发送还是异步发送。如果让发送客户端等待服务器的响应(通过调用 Future 对象的 get() 方法),显然会增加延迟(在网络上传输一个来回的延迟)。如果客户端使用回调,延迟问题就可以得到缓解,不过吞吐量还是会受发送中消息数量的限制(比如,生产者在收到服务器响应之前可以发送多少个消息)。

      • 如果 acks=-1(或all),只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。这种模式是最安全的,它可以保证不止一个服务器收到消息,就算有服务器发生崩溃,整个集群仍然可以运行。不过,它的延迟比 acks=1 时更高,因为要等待不只一个服务器节点接收消息。

      结合具体的业务场景来进行选择。

    2. 消息持久化机制,作为mq中间件,会把消息持久化到硬盘,因为内存里的数据断电就丢失了

    3. 消费者必须确认消息消费成功,否则进行重试,重试达到一定次数后,通知开发人员做好补偿措施。

    4. 关闭自动提交,当消费者消费的完成后,再手动提交,防止mq的自动提交,当消费者接收到消息后,mq以为消费者已经消费了,但这个时候消费者如果挂了,这条消息就没有被消费。

  4. 如何保证消费的顺序一致性

    大多数的项目不需要保证顺序一致性,某些特殊场景必须保证顺序一致性,比如说,mq用于保证redis和mysql的数据一致性。

    绑定同一个消费队列,消费的时候进行要注意如果使用了多线程处理,避免重新创建list,要在原来的list进行修改。

  5. mq怎么用于保证redis和数据库的数据一致性

    1. 当执行update后,发送mq去通知消费者更新redis数据

    优点:解耦,提高接口响应速度,有相应的补偿策略

    缺点:延迟比较高

    1. 监听binlog日志,结合mq,去更新redis(canal实现)

    优点:更加解耦

    缺点:延迟更高

    1. 双删策略
  6. 消费者怎么知道mq里有消息了

    两种方案:

    1. mq主动通知(push)

      当mq中有消息,就会通知消费者来进行消费。这种模型有一个致命伤,就是慢消费。

    2. 消费者轮询(pull)

      消费者去轮询看看有没有自己要消费的消息。这种模型也有弊端就是消息延迟与忙等。

      如果消费者的速度比发送者的速度慢很多,势必造成消息在mq的堆积。假设这些消息都是有用的无法丢弃的,消息就要一直在mq端保存。当然这还不是最致命的,最致命的是mq给消费者推送一堆无法处理的消息,消费者不是拒绝就是报错,然后来回踢皮球。

      反观pull模式,消费者可以按需消费,不用担心自己处理不了的消息来骚扰自己,而mq堆积消息也会相对简单,无需记录每一个要发送消息的状态,只需要维护所有消息的队列和偏移量就可以了。所以消息量有限且到来的速度不均匀的情况,pull模式比较合适。

      由于主动权在消费方,消费方无法准确地决定何时去拉取最新的消息。如果一次pull取到消息了还可以继续去pull,如果没有pull取到则需要等待一段时间重新pull。

      但等待多久就很难判定了。当然也不是说延迟就没有解决方案了,业界较成熟的做法是从短时间开始(不会对mq有太大负担),然后指数级增长等待。比如开始等5ms,然后10ms,然后20ms,然后40ms……直到有消息到来,然后再回到5ms。

      即使这样,依然存在延迟问题:假设40ms到80ms之间的50ms消息到来,消息就延迟了30ms,而且对于半个小时来一次的消息,这些开销就是白白浪费的。

      在阿里的RocketMq里,有一种优化的做法-长轮询,来平衡推拉模型各自的缺点。基本思路是:消费者如果尝试拉取失败,不是直接返回,而是把连接挂在那里等待,服务端如果有新的消息到来,把连接复用起来,这也是不错的思路。但海量的长连接mq对系统的开销还是不容小觑的,还是要合理的评估时间间隔。

  7. 如果mq宕机后,生产者怎么处理。

    生产者在向mq投递消息的时候,可以将要投递的消息记录下来(可以在数据库中插入一条数据,也可以输出相应的日志记录)后期可以编写定时任务,定期向mq发送之前发送不成功的消息。

  8. mq的消费策略

    **集群消费:**同一个消费者集群,只能消费一条消息,但是一条消息可以被多个消费者集群消费。

    广播消费:通知集群中的所有节点都进行消费(涉及到数据分片处理的场景),对数据不敏感 的场景可以采用普通hash,对数据敏感的场景可以采用hash环

使用MQ的条件

  1. 生产者不需要从消费者处获得反馈
  2. 容许短暂的不一致性
  3. MQ的解耦异步削峰大于负面影响

常见的MQ产品

  1. RabbitMQ
  2. RocketMQ
  3. ActiveMQ
  4. Kafka
  5. ZeroMQ
  6. MetaMQ
  7. Redis也可以

在这里插入图片描述

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

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

相关文章

想要用独立站打造跨境电商品牌吗?这些方法学起来吧!

随着互联网的发展,越来越多的跨境电商卖家开始考虑在独立站上打造自己的品牌。相比于在第三方平台上经营,拥有独立站不仅能够提高品牌认知度和形象,还能够更好地控制产品质量、维护顾客关系,以及获取更多的利润。而要打造一个成功…

CSS盒模型

目录 盒子区域包含块/containing block包含块的确定包含块的影响 行盒/line-boxes行盒的特性vertical-align BFCFCBFC的创建BFC的作用 关于BFC解决margin折叠问题关于设置overflow:auto解决浮动塌陷问题BFC解决塌陷问题的两个条件BFC计算高度规则 盒子区域 浏览器在展示每一个…

N-121基于微信小程序网上书城系统

开发工具:IDEA、微信小程序 服务器:Tomcat9.0, jdk1.8 项目构建:maven 数据库:mysql5.7 前端技术:vue、uniapp 服务端技术:springbootmybatisredis 本系统分微信小程序和管理后台两部分&a…

(23)目标检测算法之YOLOv6 (1)全流程指南:环境安装、模型配置、训练及推理

目标检测算法之YOLOv6 (1)全流程指南:环境安装、模型配置、训练及推理 本文向将介绍 YOLOv6 的整体框架,并提供详细的教程链接。官方论文 ☞ YOLOv6: A Single-Stage Object Detection Framework for Industrial Applicationsv3.0版本论文更新 ☞ YOLOv…

综合评价算法 | Matlab实现基于AHP层次分析法的综合评价算法

文章目录 效果一览文章概述研究内容源码设计参考资料效果一览 文章概述 综合评价算法 | Matlab实现基于AHP层次分析法的综合评价算法 研究内容 AHP的主要特点是通过建立递阶层次结构,把人类的判断转化到若干因 素两两之间重要度的比较上,从而把难于量化的定性判断转化为可操作…

测试四—测试分类

一、按测试对象划分 1.1 界面测试 界面测试(简称UI测试),指按照界面的需求(一般是UI设计稿)和界面的设计规则,对我们软件界面所展示的全部内容进行测试和检查,一般包括如下内容: 验证界面内容…

解决:在微服务中一个服务访问另一个服务的类或方法出现的问题

我的需求: 我需要在用户模块使用公共模块的service和mapper和实体类,出现以下错误 ​ springboot启动错误如下: 报错结果:需要一个类型为“com.buba.yka.mapper.salesmanMapper”的bean,但找不到该bean Error starti…

接口自动化面试题【思路分享】

文末免费领资料 接口自动化流程怎么做的,框架怎么搭建的? 流程: 1、分析需求,确定测试范围 2、搭建自动化测试环境、准备相关测试数据 3、工具选型,搭建测试框架 4、编写用例 5、执行用例,生成测试报…

记录好项目D19

记录好项目 你好呀,这里是我专门记录一下从某些地方收集起来的项目,对项目修改,进行添砖加瓦,变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是个网上商城管理系统 一、系统介绍 需求设计主要参考天猫商城的购物流…

【Linux】—— 进程的环境变量

序言: 在上期我们已经对进程PCB以及进程状态进行了详细的解释说明。今天,我将带领大家学习的是关于进程的环境变量的问题。 目录 (一)孤儿进程 1、基本介绍 2、代码演示 (二)环境变量 1、基本概念 2…

使用git管理matlab代码

matlab使用git管理代码 设置 Git 源代码管理 - MATLAB & Simulink - MathWorks 中国 在 R2020b 之前,必须安装命令行 Git 客户端,才能使用 Git 合并 MATLAB 中的分支。有关详细信息,请参阅安装命令行 Git 客户端。 1.在 Git 中注册二进…

Groovy系列三 Java SpringBoot 整合 Groovy

目录 一、概述 一、在Java中使用Groovy: 二、在Groovy中使用Java: 三、几种范式的不同、优缺点 Java调用Groovy的类和方法: Groovy调用Java的类和方法: 使用GroovyShell执行Groovy脚本: 使用GroovyClassLoader加…

4.0ORBSLAM3之局部建图线程概述

1.简介 局部建图线程是ORBSLAM3的核心线程之一,在初始化SLAM系统时被创建和启动,主要作用是为跟踪线程(跟踪局部地图)以及回环检测线程(回环检测)服务,并进行局部地图优化以及时消除轨迹的累计误差。局部建图线程主要维护一个由共视图Covisi…

JSP网上订餐管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 网上订餐管理系统是一套完善的web设计系统,对理解JSP java SERLVET mvc编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,eclipse开发,数据库为Mysql5.0&a…

java压测工具 Jmeter初使用

一. 下载及安装教程 1. 有博主总结的很好,这里直接放传送门: 【Jmeter】win 10 / win 11:Jmeter 下载、安装、汉化、新机迁移、版本更新(Jmeter 4 以上版本均适用) 2. Jmeter 自定义创建桌面快捷方式 3. JMeter插件…

手写vue-diff算法(三)updateChildren

前文回顾 上一篇提到,新老儿子节点比对可能存在的 3 种情况及对应的处理方法: 情况 1:老的有儿子,新的没有儿子 处理方法:直接将多余的老dom元素删除即可; 情况 2:老的没有儿子,…

基础知识--客户端·服务端·代理

目录 一、客户端 1.什么是客户端 2.客户端分类 二、服务端 1.什么是服务器 2.服务器的作用 3.服务器工作原理 4.服务器的组成 服务器硬件 服务器软件 5.补充 三、代理 1.代理的分类 正向代理 反向代理 两者的区别与联系 2.总结 一、客户端 1.什么是客户端 …

【八股】【C++】(二)函数、类、模板

这里写目录标题 形参与实参的区别函数调用过程指针和引用当函数参数回调函数友元函数重载匹配运算符重载直接初始化与拷贝初始化函数指针C中struct(结构)和class(类)的区别C有哪几种构造函数构造函数的执行顺序析构函数的执行顺序…

设计消息模块的业务层Web层

目录 业务层 一、定义Message业务接口 二、定义Message业务实现类 Web层 一、获取分页消息列表 二、根据ID查询消息 三、把未读消息更新成已读消息 四、删除消息 业务层 一、定义Message业务接口 创建 MessageService.java 类 public interface MessageService {pub…

mybatis-plus使用@Delete注解批量删除实战

使用Delete注解批量删除 1、控制器调用 // test // http://localhost:3000/function/test // 删除操作按钮权限 Transactional GetMapping("/test") public JSONObject testBatch() {// Arrays.asList(1, 2, 3)JSONObject result new JSONObject();try {functionM…