消息中间件常见知识点

029443e864c547c598d343976f7df9ab.gif一:消息队列的主要作用是什么?

 

1.消息队列的特性:

 

业务无关,一个具有普适性质的消息队列组件不需要考虑上层的业务模型,只做好消息的分发就可以了,上层业务的不同模块反而需要依赖消息队列所定义的规范进行通信。FIFO,先投递先到达的保证是一个消息队列和一个buffer的本质区别。容灾,对于普适的消息队列组件来说,节点的动态增删和消息的持久化,都是支持其容灾能力的重要基本特性。性能,这个不必多说了,消息队列的吞吐量上去了,整个系统的内部通信效率也会有提高。

 

2.为什么需要消息队列:

 

当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消息队列,作为抽象层,弥合双方的差异。“ 消息 ”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。消息被发送到队列中,“ 消息队列 ”是在消息的传输过程中保存消息的容器 。

 

使用场景:

 

业务系统触发短信发送申请,但短信发送模块速度跟不上,需要将来不及处理的消息暂存一下,缓冲压力。就可以把短信发送申请丢到消息队列,直接返回用户成功,短信发送模块再可以慢慢去消息队列中取消息进行处理。

调远程系统下订单成本较高,且因为网络等因素,不稳定,攒一批一起发送。

任务处理类的系统,先把用户发起的任务请求接收过来存到消息队列中,然后后端开启多个应用程序从队列中取任务进行处理。

3.使用消息队列有什么好处(消息队列作用):

 

异步:假设你有一个系统调用链路,是系统A调用系统B,一般耗时20ms;系统B调用系统C,一般耗时200ms;系统C调用系统D,一般耗时2s。用户一个请求过来巨慢无比,因为走完一个链路,需要耗费:2220ms,如果业务流程支持异步化的话,是不是就可以考虑把系统C对系统D的调用抽离出去做成异步化的,不要放在链路中同步依次调用。这样,实现思路就是系统A -> 系统B -> 系统C,直接就耗费220ms后直接成功了。然后系统C就是发送个消息到MQ中间件里,由系统D消费到消息之后慢慢的异步来执行这个耗时2s的业务处理。通过这种方式直接将核心链路的执行性能提升了10倍。

解耦:假设你有个系统A,这个系统A会产出一个核心数据,现在下游有系统B和系统C需要这个数据。那简单,系统A就是直接调用系统B和系统C的接口发送数据给他们就好了。但是现在要是来了系统D、系统E、系统F、系统G,等等,十来个其他系统慢慢的都需要这份核心数据呢?那么负责系统A的就要被烦死了,然后如果要是某个下游系统突然宕机了呢?系统A的调用代码里是不是会抛异常?那系统A的同学会收到报警说异常了,结果他还要去care是下游哪个系统宕机了。所以在实际的系统架构设计中,如果全部采取这种系统耦合的方式,在某些场景下绝对是不合适的,系统耦合度太严重。并且互相耦合起来并不是核心链路的调用,而是一些非核心的场景(比如上述的数据消费)导致了系统耦合,这样会严重的影响上下游系统的开发和维护效率。因此在上述系统架构中,就可以采用MQ中间件来实现系统解耦,系统A就把自己的一份核心数据发到MQ里,下游哪个系统感兴趣自己去消费即可,不需要了就取消数据的消费。

消峰:假设有一个系统,平时正常的时候每秒可能就几百个请求,正常处理都是OK的,在高峰期一下子来了每秒钟几千请求,弹指一挥间出现了流量高峰,此时我们就可以用MQ中间件来进行流量削峰。所有机器前面部署一层MQ,平时每秒几百请求大家都可以轻松接收消息。一旦到了瞬时高峰期,一下涌入每秒几千的请求,就可以积压在MQ里面,然后那一台机器慢慢的处理和消费。等高峰期过了,再消费一段时间,MQ里积压的数据就消费完毕了。这个就是很典型的一个MQ的用法,用有限的机器资源承载高并发请求,如果业务场景允许异步削峰,高峰期积压一些请求在MQ里,然后高峰期过了,后台系统在一定时间内消费完毕不再积压的话,那就很适合用这种技术方案。

4.消息队缺点:

 

系统可用性降低:系统引入的外部依赖越多,越容易挂掉,本来就是A系统调用BCD三个系统的接口就好了,人ABCD四个系统好好的,偏加个MQ进来,万一MQ挂了,整套系统崩溃了。

系统复杂性提高:硬生生加个MQ进来,怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性?

一致性问题:A系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是BCD三个系统那里,BD两个系统写库成功了,结果C系统写库失败了,这数据就不一致了。

 

二:如何保证消息队列的高可用?

1.RabbitMQ高可用

 

单机模式:Demo级别的,生产环境不会使用

 

普通集群模式:

 

 

 

 

 

 

 

同时部署多台RabbitMQ服务器,当生产者将消息发送到RabbitMQ的集群中时 ,消息会存在元数据(类似于消息的描述信息)+消息数据,收到消息的MQ会将消息的元数据信息同步到其他的节点上,当消费者从任意一台服务器上获取消息时,如果当前服务器存在该消息的数据信息就获取成功,否则就会根据元数据信息从其他节点上获取消息数据,这样做并没有保证MQ的高可用,因为存在消息数据的服务器挂掉,消息一样不存在,这样做只能保证MQ的吞吐量比较大。

 

采用镜像集群模式:

 

 

 

 

 

 

 

你创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。 这样的话,好处在于,你任何一个机器宕机了,别的机器都可以用。坏处在于

 

性能开销大,消息同步所有机器,导致网络带宽压力和消耗很重!

没有扩展性,如果某个queue负载很重,你加机器,新增的机器也包含了这个queue的所有数据,并没有办法线性扩展你的queue  

开启镜像集群模式:rabbitmq有很好的管理控制台,在后台新增一个策略,这个策略是镜像集群模式的策略,指定的时候可以要求数据同步到所有节点的,也可以要求就同步到指定数量的节点,然后你再次创建queue的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。

 

2.kafka的高可用

 

 

 

 

 

 

 

kafka一个最基本的架构认识:多个broker组成,每个broker是一个节点;你创建一个topic,这个topic可以划分为多个partition,每个partition可以存在于不同的broker上,每个partition就放一部分数据。

 

这就是天然的分布式消息队列,就是说一个topic的数据,是分散放在多个机器上的,每个机器就放一部分数据。kafka 0.8以前,是没有HA机制的,就是任何一个broker宕机了,那个broker上的partition就废了,没法写也没法读,没有什么高可用性可言。kafka 0.8以后,提供了HA机制,就是replica副本机制。每个partition的数据都会同步到其他机器上,形成自己的多个replica副本。然后所有replica会选举一个leader出来,那么生产和消费都跟这个leader打交道,然后其他replica就是follower。写的时候,leader会负责把数据同步到所有follower上去,读的时候就直接读leader上数据即可。只能读写leader?很简单,要是你可以随意读写每个follower,那么就要care数据一致性的问题,系统复杂度太高,很容易出问题。kafka会均匀的将一个partition的所有replica分布在不同的机器上,这样才可以提高容错性。

 

写数据的时候,生产者就写leader,然后leader将数据落地写本地磁盘,接着其他follower自己主动从leader来pull数据。一旦所有follower同步好数据了,就会发送ack给leader,leader收到所有follower的ack之后,就会返回写成功的消息给生产者。(当然,这只是其中一种模式,还可以适当调整这个行为)

 

消费的时候,只会从leader去读,但是只有一个消息已经被所有follower都同步成功返回ack的时候,这个消息才会被消费者读到。

 

三:高并发情况下消息队列满了如何防止消息丢失?

其实这个防止消息丢失,每种MQ都要从三个角度来分析:生产者弄丢数据、消息队列弄丢数据、消费者弄丢数据,以RabbitMQ为例:

 

1.生产者丢数据:

 

从生产者弄丢数据这个角度来看,RabbitMQ提供transaction和confirm模式来确保生产者不丢消息。transaction机制就是说,发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事物就会回滚(channel.txRollback()),如果发送成功则提交事物(channel.txCommit())。然而缺点就是吞吐量下降了。因此,生产上用confirm模式的居多。一旦channel进入confirm模式,所有在该信道上面发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后,rabbitMQ就会发送一个Ack给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了.如果rabiitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。

 

2.消息队列丢数据

 

处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。那么如何持久化呢,这里顺便说一下吧,其实也很容易,就下面两步:

 

将queue的持久化标识durable设置为true,则代表是一个持久的队列

发送消息的时候将deliveryMode=2

这样设置以后,rabbitMQ就算挂了,重启后也能恢复数据

 

3.消费者丢数据

 

消费者丢数据一般是因为采用了自动确认消息模式。这种模式下,消费者会自动确认收到信息。这时rahbitMQ会立即将消息删除,这种情况下如果消费者出现异常而没能处理该消息,就会丢失该消息。至于解决方案,采用手动确认消息即可。

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈Acrel-2000MG微电网能量管理系统在新能源储能行业中的设计与应用-安科瑞 蒋静

概述:在新型电力系统中新能源装机容量逐年提高,但是新能源比如光伏发电、风力发电是不稳定的能源,所以要维持电网稳定,促进新能源发电的消纳,储能将成为至关重要的一环,是分布式光伏、风电等新能源消纳以及电网安全的必…

亚信安慧AntDB数据并行加载工具的实现(一)

1.概述 数据加载速度是评判数据库性能的重要指标,能否提高数据加载速度,对文件数据进行并行解析,直接影响数据库运维管理效率。基于此,AntDB分布式数据库提供了两种数据加载方式: 一是类似于PostgreSQL的Copy命令&am…

计算机网络物理层 习题答案及解析

2-1 下列选项中,不属于物理层接口规范定义范畴的是( D )。 A. 引脚功能 B. 接口形状 C. 信号电平 D. 传输媒体 【答案】D 【解析】 2-2 某网络在物理层规定,信号的电平范围为- 15V~15V , 电线长…

2024年AI领域的突破性进展预测

🦉 AI新闻 🚀 2024年AI领域的突破性进展预测 摘要:23年被誉为生成式AI之年,24年AI有哪些新突破?GPT-5发布后,LLM在本质上仍然有限,基本的AGI也不足以实现。然而,英伟达高级科学家和…

【Unity引擎技术整合】 Unity学习路线 | 知识汇总 | 持续更新 | 保持乐趣 | 共同成长

前言 本文对Unity引擎的知识进行了一个整理总结,基本包含了Unity中大部分的知识介绍。网上也有很多Unity相关的学习资料,但大多数都不成体系,学起来的时候难免会东奔西走的摸不着头脑。本文整理的多数文章都是有对应的系列性文章专栏&#x…

linux休眠机制介绍

一、概述 Linux系统提供了休眠和低功耗模式,可以帮助节省电力和延长电池寿命,休眠对应的另外一种模式就是唤醒。 二、常用的休眠方式 常用的休眠方式有freeze,standby, mem, disk,hibernate freeze: 冻结所有的进程,包括用户空…

HTML进阶

列表、表格、表单 文章目录 列表、表格、表单01-列表无序列表有序列表定义列表 02-表格表格结构标签-了解合并单元格 03-表单input 标签input 标签占位文本单选框上传文件多选框下拉菜单文本域label 标签按钮 04-语义化无语义的布局标签有语义的布局标签 05-字符实体 01-列表 …

vue中的内置指令v-model的作用和常见使用方法以及自定义组件上的用法

一、v-model是什么 v-model是Vue框架的一种内置的API指令,本质是一种语法糖写法,它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。在Vue中,v-model是用于在表单元素和组件之间创建双向数据绑定的指令。它…

第二节 linux操作系统安装与配置

一:Vmware虚拟机安装与使用   ①VMware是一个虚拟PC的软件,可以在现有的操作系统上虚拟出一个新的硬件环境,相当于模拟出一台新的PC ,以此来实现在一台机器上真正同时运行多个独立的操作系统。   ②VMware主要特点&#xff1a…

初识RabbitMQ

1.什么是MQ? MQ翻译为消息队列,通过典型的生产者和消费者模型,生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的…

m1芯片电脑上的paragon15如何安装激活 m1芯片电脑上ntfs for mac如何安装

Paragon NTFS软件在M1芯片电脑上安装之后,最后一步会让我们“允许加载第三方内核扩展”,具体如下图所示。 图1:允许加载第三方内核扩展 按照图中提示“单击此处“,然后打开安全与隐私。接下来依次点击小锁标志进行解锁&#xff0c…

uni-app 前后端调用实例 基于Springboot 下拉刷新实现

锋哥原创的uni-app视频教程: 2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中...共计23条视频,包括:第1讲 uni…

java 纯代码导出pdf合并单元格

java 纯代码导出pdf合并单元格 接上篇博客 java导出pdf(纯代码实现) 后有一部分猿友叫我提供一下源码,实际上我的源码已经贴在帖子上了,都是同样的步骤,只是加多一点设置就可以了。今天我再次上传一下相对情况比较完整…

Vue2中使用echarts,并从后端获取数据同步

一、安装echarts npm install echarts -S 二、导入echarts 在script中导入&#xff0c;比如&#xff1a; import * as echarts from "echarts"; 三、查找要用的示例 比如柱状图 四、初始化并挂载 <template><div id"total-orders-chart" s…

C语言与人生:数组交换和二分查找

少年们&#xff0c;大家好。我是博主那一脸阳光&#xff0c;今天和分享数组交换和二分查找。 前言&#xff1a;探索C语言中的数组交换操作与二分查找算法 在计算机编程领域&#xff0c;特别是以C语言为代表的低级编程语言中&#xff0c;对数据结构的理解和熟练运用是至关重要的…

【AIGC-图片生成视频系列-4】DreamTuner:单张图像足以进行主题驱动生成

目录 一. 项目概述 问题&#xff1a; 解决&#xff1a; 二. 方法详解 a) 整体结构 b) 自主题注意力 三. 文本控制的动漫角色驱动图像生成的结果 四. 文本控制的自然图像驱动图像生成的结果 五. 姿势控制角色驱动图像生成的结果 2023年的最后一天&#xff0c;发个文记录…

再薅!Pika全球开放使用;字节版GPTs免费不限量;大模型应用知识地图;MoE深度好文;2024年AIGC发展轨迹;李飞飞最新自传 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f440; 终于&#xff01;AI视频生成平台 Pika 面向所有用户开放网页端 https://twitter.com/pika_labs Pika 营销很猛&#xff0c;讲述的「使…

虚幻UE 材质-PDO像素深度偏移量

2024年的第一天&#xff01;&#xff01;&#xff01;大家新年快乐&#xff01;&#xff01;&#xff01; 可能是长大了才知道 当你过得一般 你的亲朋好友对你真正态度只可能是没有表露出来的冷嘲热讽了 希望大家新的一年平安、幸福、 永远活力满满地追求自己所想做的、爱做的&…

1. Spring概述

概述 Spring 是一个开源框架Spring 为简化企业级开发而生&#xff0c;使用 Spring&#xff0c;JavaBean 就可以实现很多以前要靠 EJB 才能实现的功能。同样的功能&#xff0c;在 EJB 中要通过繁琐的配置和复杂的代码才能够实现&#xff0c;而在 Spring 中却非常的优雅和简洁。…

SSM框架

SSM框架 一、Spring 1、Spring框架概述&#xff1a; 1.spring是一个轻量级的开源javaEE框架&#xff0c;简化开发 2.spring可以解决企业应用开发的复杂性 3.spring的两个核心部分&#xff1a;IOC和AOP &#xff08;1&#xff09;IOC&#xff1a;控制反转&#xff0c;将创…