java学习——消息队列MQ

news2025/1/11 5:42:56

上一篇传送门:点我

目前只学习了RabbitMQ,后续学习了其他MQ后会继续补充。

MQ有了解过吗?说说什么是MQ?

MQ是Message Queue的缩写,也就是消息队列的意思。它是一种应用程序对应用程序的通信方法,使得应用程序能够通过读写出入队列的消息来进行通信,而无需使用专用的连接来链接它们。消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削峰等问题,实现高性能,高可用,可伸缩和最终一致性架构。在消息队列中,有生产者消费者两个角色。生产者负责发送数据到消息队列,而消费者则从消息队列中取出数据进行处理。这种方式实现了生产者与消费者之间的解耦,使得它们可以独立地运行和扩展。

消息队列的优缺点有哪些?

优点:
1.应用解耦:消息队列允许生产者和消费者之间松耦合。生产者只需要将消息发送到队列,而不需要关心消费者何时或如何处理这些消息。
2.异步处理:消息队列允许异步处理消息,这意味着接收者可以在自己方便的时候处理消息,而不是立即响应。这可以提高系统的吞吐量和响应时间。
3.流量削峰:在高并发场景下,消息队列可以起到缓冲作用,平滑突发流量,保护后端系统免受冲击。

缺点:
1.可用性降低:如果消息队列服务成为单点故障,整个系统可能会受到影响。因此,需要实施高可用性和容错策略,一般解决方法是给MQ架集群。
2.复杂性提高:引入消息队列会增加系统的复杂性。因为需要配置和管理消息队列服务,同时还需要处理可能的消息丢失、重复或顺序错乱等问题。
3.一致性问题:在分布式系统中使用消息队列时,如果消息队列发生了消息的丢失与重复,则可能会遇到数据一致性的问题。

说说消息队列的应用场景

消息队列的应用场景主要分为以下三种:
1.异步处理:应用在实时性要求不高的一些场景,例如用户注册发送验证码、下单通知发送优惠券等。这些场景下,服务方只需要把协商好的消息发送到消息队列,剩下的由消费者的消息服务去处理,不需要等待消费者的返回结果就可以直接返回给客户端,返回给业务层面;
2.应用解耦:可以把一些相关的但是耦合度不高的一些系统关联起来,比如订单系统与优惠券积分系统有关联度,但是没有那么紧密,每个系统之间只需要把一些约定好的消息发送到MQ,另外的系统直接去消费就可以了,它可以允许各类系统间采用不同的一些框架和语言来实现,从而大大增加了整个系统的灵活度;
3.流量削峰:应用在大流量入口的一些短时间的业务,短时间内业务需求处理不完的一些服务,例如双十一秒杀、演唱会抢票等。为了权衡高可用把大量的一些并行任务发送给MQ。根据MQ的存储和分发功能平稳的去处理后续的一些业务,从而起到大流量缓冲的作用。

开发过程中有哪些MQ可以选择?如何技术选型?

目前市面上常见的消息队列中间件主要有RabbitMQ、ActiveMQ、RocketMQ、Kafka。这几种消息队列各有优缺点,具体如下:

在这里插入图片描述
由上可以看出,ActiveMQ相较于其它三种消息队列,可用性差,并且吞吐量、消息延迟、可靠性都一般,除了一些小型项目或是追求经济高效的特定需求,ActiveMQ不是消息队列的第一选择,所以现在ActiveMQ不是主流的消息队列了
而由于RabbitMQ是基于Erlang语言开发的,所以如果需要对现有消息队列去做进一步的开发,不推荐使用RabbitMQ(如果只是拿来做简单应用开发就没区别)。
从吞吐量来看,比较好的是RocketMQ和Kafka,其中最好的是Kafka(单机的并发吞吐能力能够达到百万量级),所以如果要追求极致的吞吐能力去处理一些海量数据传输的大数据业务的时候,Kafka会是更好的选择。
而吞吐量高也会带来一定的牺牲,RocketMQ和Kafka的消息延迟(毫秒级)相比RabbitMQ(微秒级)要久很多,如果要追求消息的低延迟就可以选择RabbitMQ。
从可靠性的角度来看,Kafka由于追求极致的并发吞吐量,所以消息可靠性一般,如果要考虑消息的高可靠性,可以选择RabbitMQ或RocketMQ。

说说RabbitMQ的基本架构设计

RabbitMQ的基本架构由以下几个部分组成:
1.生产者(Producer):生产者是消息的发送方,负责产生并发生消息到RabbitMQ。生产者通常将消息发生给交换机(Exchange),从而使其消费者没有强关联。
2.交换机(Exchange):交换机是消息的分发中心,负责将接收到的消息路由到一个或多个消息队列。它定义了消息的传递规则,可以根据规则将消息发送到一个或多个队列中。

  • 直连交换机(Direct Exchange):将消息路由到与消息中的路由键(Routing Key)完全匹配的队列;
  • 主题交换机(Topic Exchange):根据通配符匹配路由键(Routing Key),将消息路由到一个或多个队列;
  • 扇出交换机(Fanout Exchange):将消息广播到所有与交换机绑定的队列,忽略路由键;
  • 头部交换机(Headers Exchange):根据消息头中的属性进行匹配,将消息路由到与消息头匹配的队列。

3.队列(Queue):队列是消息的存储区,用于存储生产者发送的消息。消息最终会被消费者从队列中取出并处理。每个队列都有一个名称,并且可以绑定到一个或多个交换机。
4.消费者(Consumer):消费者是消息的接收方,负责从队列中获取消息并进行处理。消费者通过订阅队列来接收消息。
5.绑定(binding):绑定是交换机和队列之间的关联关系。生产者将消息发送到交换机,而队列通过绑定与交换机相连,从而接收消息。
6.虚拟主机(Virtual Host):虚拟主机是RabbitMQ的基本工作单元,每个虚拟主机都拥有自己独立的用户、权限、交换机、队列等资源,完全隔离于其他虚拟主机。
7.连接(Connection):连接是指生产者、消费者与RabbitMQ之间的网络连接。每个连接都可以包含多个信道(Channel),每个信道是一个独立的会话通道,可以进行独立的消息传递。
8.消息(Message):消息是生产者和消费者之间传递的数据单元。消息通常会包含消息体和可选的属性,如路由键等。

在这里插入图片描述

说说RabbitMQ的交换机类型

1.Direct Exchange(直连交换机)
此类型交换机通过RoutingKey路由键将交换机和队列进行绑定,消息被发送到exchange时,需要根据消息的RoutingKey来进行匹配,只将消息发送到完全匹配此RoutingKey的队列。
2.Fanout Exchange(扇出交换机)
此类型交换机会将消息分发给所有绑定了此交换机的队列,此时RoutingKey无效。在Fanout类型交换机下发送一条消息,无论RoutingKey是什么,所有队列均可收到消息。
3.Topic Exchange(主题交换机)
此类型交换机与Direct类似,也是需要通过RoutingKey路由键进行匹配分发,区别在于Topic可以进行模糊匹配,而Direct是完全匹配。
1.在Topic中,将RoutingKey通过“.”来划分为多个部分;
2.“*”:代表一个部分;
3.“#”:代表0个或多个部分(如果绑定的路由键为“#”时,则接受所有消息,因为路由键所有都匹配)
4.Header Exchange(头部交换机)
Headers Exchange匹配AMQP消息的header而不是路由键,此外headers交换机和direct交换机完全一致,但由于它的性能差,目前几乎用不到了。
在此类交换机中,消费方指定的headers中必须包含一个“x-match”的键。该键的值有两个:
1.x-match = all:表示所有的键值对都匹配才能接收到消息
2.x-match = any:表示只要有键值对匹配就能接受到消息

说说RabbitMQ的持久化机制

RabbitMQ的持久化是一个重要的功能,它确保了即使在RabbitMQ服务器意外关闭或重启的情况下,消息仍然能够得到保存和恢复。RabbitMQ的持久化包括三个方面:交换器的持久化、队列的持久化和消息的持久化
交换器的持久化是通过在声明交换器时指定Durability参数为durable实现的。如果交换器不设置持久化,那么在RabbitMQ服务重启之后,相关的交换器元数据会丢失,但消息不会丢失,只是不能将消息发送到这个交换器中。
队列的持久化也是通过在声明队列时指定Durability参数为durable实现的。如果队列不设置持久化,在RabbitMQ服务重启之后,相关队列的元数据和消息数据都会丢失。设置队列持久化可以确保队列本身的元数据不会因异常情况而丢失,但并不能保证内部所存储的消息不会丢失。为了确保消息不会丢失,需要将消息设置为持久化。
消息的持久化可以通过消息的投递模式来实现。将消息设置为持久化可以确保消息在RabbitMQ服务器意外关闭或重启后能够得到恢复。然而,将所有消息都设置为持久化会严重影响RabbitMQ服务器的性能,因为写入磁盘的速度比写入内存的速度慢得多。因此,在选择是否要将消息持久化时,需要在可靠性和吞吐量之间做一个权衡

如何保证RabbitMQ的消息可靠性传输(保证消息不丢失)?

在RabbitMQ的整个消息投递过程中,有以下三种情况会存在消息丢失的问题:

1.生产者把消息发送到RabbitMQ Server的过程中丢失;
2.RabbitMQ Server收到消息后,在持久化之前宕机导致数据丢失;
3.消费端收到消息后还未来得及处理便宕机,导致RabbitMQ Server认为这个消息已经签收,这个消息就无法重复投递,导致消息无法消费的问题。

所以只需要解决这三个角度的问题,就能保证消息的可靠传输。
从生产者发送消息到Server端的角度来说,RabbitMQ提供了一个Confirm的消息确认机制,也就是说生产者发送的消息到Server端后,如果消息处理成功,Server端会返回客户端一个ack的消息,那么客户端可以根据消息的处理结果来决定是否要对消息进行重新发送,从而确保消息一定要到达到RabbitMQ Server端上;
从Server端的角度来说,可以开启消息的持久化机制,也就是收到消息后,将消息持久化到磁盘里面,设置消息的持久化一般有两个步骤:首先在创建Queue的时候设置为持久化,然后在发送消息的时候,把消息投递模式设置为持久化投递。虽然设置了持久化消息,但是也有可能会出现问题,比如消息刷新到磁盘上之前,RabbitMQ的Server端就发生宕机,这还是会导致消息丢失。为了确保万无一失,需要结合Confirm消息确认机制来一起使用;
从消费者的角度来看,可以把消息的ack机制中的自动确认修改为手动确认(将auto_ack参数设置为false),也就是说消费端只有手动调用消息确认方法,才表示这个消息已经被签收,这种方式可能会造成消息的重复消费,所以还需要考虑到幂等性的设计。

RabbitMQ中如何保证消息不被重复消费?

保证消息不被重复消费,实际上就是解决消息消费端幂等问题 (幂等性,指的是一条指令,任意多次执行所产生的影响均与一次执行的影响相同)。所以只要消费端具备了幂等性,消息重复消费的问题就解决了。
实现消息幂等性可以采用以下两种方案:
1.使用数据库的唯一约束实现幂等,比如对于MQ中的消息,设置一个唯一的消息id,如果消费端多次消费,就会触发数据库的唯一约束异常,从而实现消息的幂等性。
2.使用redis中的setNX指令,在MQ中,为了避免MQ重复消费导致数据被多次修改,消费端可以在接收到消息时,把消息通过setNX写入到redis里面,这样一来一旦消息被消费过,就不会再次被消费。

RabbitMQ中如何解决消息堆积问题?

在RabbitMQ中,出现消息堆积问题的场景一般有以下几种:
1.消息被消费方拒绝,一般来说这种情况是出现在程序或是逻辑有问题的时候。
解决方法:通过添加死信队列或是日志记录的方式避免消息重新入队
2.消费者消费消息的速度慢,从而导致消息的堵塞堆积。
解决方法:通过优化程序代码或建立消费者集群的方式增加消费者的消费能力。
3.队列容量不够,也可能导致消息堆积。
解决方法:增加队列的容量,以容纳更多的待处理消息。

RabbitMQ如何保证消息的顺序消费?

我们说的保证顺序消费,说的是消费者消费信息的顺序。虽然Server端队列中的消息是顺序的,但是由于多个消费者并发消费消息,所以获取消息的速度不一样,从而可能会导致消息的消费顺序出现问题。
想要解决顺序消费的问题,通常的解决办法就是一个队列只有一个消费者,这样就可以一个个消息按顺序处理,但缺点就是并发能力下降,无法并发消费消息,这是个取舍的问题。
也可以在发送消息时使用一些标识符或分区键将消息分区,并确保具有相同标识符的消息被发送到同一个队列。然后,可以使用多个消费者,每个消费者处理一个特定的分区,从而保证了消息在特定分区内的顺序性。

RabbitMQ如何给消息设置过期时间?

在RabbitMQ中存在2种方法设置消息的过期时间。第一种方法是通过对队列进行设置,这种设置后,该队列中所有的消息都存在相同的过期时间;第二种方法是通过对消息本身进行设置,那么每条消息的过期时间都不一样。如果同时使用这两种方法,那么以过期时间较小的哪个数值为准。当消息达到过期时间还没有被消费,那么该消息就成为了一个死信消息
队列设置:在队列中声明的时候使用x-message-ttl参数,单位为 毫秒。
单个消息设置:设置消息属性的expiration参数的值,单位为 毫秒。

说说RabbitMQ的死信队列

当队列中的消息被拒绝、或者消息过期会变成死信,死信可以被重新发布到另一个交换机,这个交换机是死信交换机(DLX,Dead Letter Exchange),与DLX绑定的队列被称为死信队列
出现死信的原因一般有以下几点:1.消息被消费方拒绝(消费方使用channel.basicNack或channel.basicReject,并且此时requeue属性被设置为false);2.消息超出过期时间超时;3.消息总量超过了队列的最大长度

说说RabbitMQ的延迟队列

延迟队列存储的是延迟消息。延迟消息是指,当消息被发布出去后,并不立即投递给消费者,而是在指定时间之后投递。例如:在订单系统中,订单有30秒的付款时间,在订单超时之后再投递给消费者处理超时订单。
RabbitMQ没有直接支持延迟队列,可以通过死信队列来实现。在死信队列中,可以为普通交换机绑定多个消息队列,假设绑定过期时间为5分钟,10分钟和30分钟三个消息队列,然后为每个消息队列设置DLX,为每个DLX关联一个死信队列。
当消息过期后,消息会被转存到对应的死信队列中,然后投递给指定的消费者消费。

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

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

相关文章

Apache Zeppelin 命令执行漏洞复现(CVE-2024-31861)

0x01 产品简介 Apache Zeppelin 是一个让交互式数据分析变得可行的基于网页的开源框架,Zeppelin提供了数据分析、数据可视化等功能, 0x02 漏洞概述 Apache Zeppelin 中代码生成控制不当(“代码注入”)漏洞。攻击者可以使用 She…

Springboot集成Ehcache3实现本地缓存

如果只需要在单个应用程序中使用本地缓存&#xff0c;则可以选择Ehcache&#xff1b;它支持内存和磁盘存储&#xff0c;这里不以注解方式演示&#xff0c;通过自己实现缓存管理者灵活控制缓存的读写&#xff1b; 1、引入相关依赖 <!-- ehcache3集成start --><depende…

蓝色系UX/UI设计求职面试作品集模版figmasketchPPT可编辑源文件

页面数量: 20P 页面尺寸:1920*1080PX 交付格式&#xff1a;figma、sketch、PPT 赠送文件&#xff1a;24款高质量样机&#xff08;PSD格式&#xff09; 该作品集虽然只有20页&#xff0c;但可根据需求复制作品集里已有的页面作为模版来扩展您的设计项目 该作品集模版可编辑可修…

MySQL (索引 事务)

索引 索引是一种特殊的文件, 包含着对于数据库里所有数据的引用指针. 可以对表中的一列或多列创建索引, 并指定索引类型, 各类索引有各自的数据结构实现 索引的目的在于 快速定位, 检索数据 索引可以提高 查找 效率, 但会增加 增删改 的开销 索引创建好之后, 每次调用 查询操作…

探索顶级短视频素材库:多样化选择助力创作

在数字创作的浪潮中&#xff0c;寻找优质的短视频素材库是每位视频制作者的必经之路。多种短视频素材库有哪些&#xff1f;这里为您介绍一系列精选的素材库&#xff0c;它们不仅丰富多样&#xff0c;而且高质量&#xff0c;能极大地提升您的视频创作效率和质量。 1.蛙学网 蛙学…

华火电焰灶全国经销商加盟_优势怎么样_费用多少_华焰天下

随着科技的不断进步&#xff0c;电焰灶作为现代厨房的重要设备&#xff0c;其市场需求持续增长。华火电焰灶&#xff0c;凭借其独特的技术优势和广泛的市场前景&#xff0c;吸引了众多投资者的目光。本文将从华火电焰灶的优势、加盟费用以及华焰天下的机遇三个方面&#xff0c;…

【gdb调试】在ubuntu环境使用gdb调试一棵四层二叉树的数据结构详解

目录 &#x1f31e;1. 整体思路 &#x1f31e;2. 准备内容 &#x1f33c;2.1 配置.c文件 &#x1f33c;2.2 准备测试程序 &#x1f33c;2.3 GDB调试基础 &#x1f31e;3. GDB调试四层二叉树 &#x1f33c;3.1 测试程序分析 &#x1f33c;3.2 gdb分析 &#x1f33b;1. …

OpenHarmony轻量系统开发【3】代码编译和烧录

3.1源码目录 下载完代码后&#xff0c;大家可以进入代码目录&#xff1a; 这里重点介绍几个比较重要的文件夹&#xff1a; 1 vendor文件夹 该文件夹存放的是厂商相关的配置&#xff0c;包括组件配置、HDF相关配置&#xff0c;代码目录如下&#xff1a; 可以看到有hisilicon文…

LLMs之ToolAlpaca:ToolAlpaca(通用工具学习框架/工具使用语料库)的简介、安装和使用方法、案例应用之详细攻略

LLMs之ToolAlpaca&#xff1a;ToolAlpaca(通用工具学习框架/工具使用语料库)的简介、安装和使用方法、案例应用之详细攻略 目录 ToolAlpaca的简介 0、《ToolAlpaca: Generalized Tool Learning for Language Models with 3000 Simulated Cases》翻译与解读 1、数据集列表 2…

连续上榜!Coremail连续十一次入选《中国网络安全行业全景图》

4月12日&#xff0c;国内专业权威咨询机构——安全牛&#xff0c;正式发布第十一版《中国网络安全行业全景图》&#xff08;以下简称“全景图”&#xff09;。该全景图包含了16项一级安全分类&#xff0c;108项二级安全分类&#xff0c;共收录454家网络安全厂商。 Coremail作为…

【保姆级】2024年OnlyFans订阅指南

OnlyFans是一个独特的社交媒体平台&#xff0c;它为创作者和粉丝提供了一个互动交流的空间。通过这个平台&#xff0c;创作者可以分享他们的独家内容&#xff0c;而粉丝则可以通过订阅来支持和享受这些内容。如果你对OnlyFans感兴趣&#xff0c;并希望成为其中的一员&#xff0…

D365开发-在视图按钮的js里,引用别的js里的公共方法

公共方法写法&#xff1a; "use strict"; var JJMC window.JJMC || {}; JJMC.SamMCommon JJMC.SamMCommon || {}; (function () { this.cloneRecord function (excludeAttrbuteNames){ / } }).call(JJMC.SamMCommon); 然后在需要调方法的command里面&#xff0c;之…

PNPM 8管理Node版本,卸载了旧版本Node找不到PNPM

前言 用 pnpm env 来管理 node 的版本&#xff0c;安装了新版本之后&#xff0c;卸载了之前的旧版本&#xff0c;调用 pnpm 报错 异常截图 解决方式 从终端获取报错文件到路径&#xff0c;进入编辑修改错误的 node bin 路径为正确的 node 启动路径即可也就是修改 "/Use…

vite+vue3+antDesignVue 记录-持续记录

记录学习过程 持续补充 每天的学习点滴 开始时间2024-04-12 1&#xff0c;报错记录 &#xff08;1&#xff09;env.d.ts文件 解决方法&#xff1a; 在env.d.ts文件中添加以下代码&#xff08;可以看一下B站尚硅谷的讲解视频&#xff09; declare module *.vue {import { Defi…

SpringBoot基于RabbitMQ实现消息延迟队列方案

知识小科普 在此之前&#xff0c;简单说明下基于RabbitMQ实现延时队列的相关知识及说明下延时队列的使用场景。 延时队列使用场景 在很多的业务场景中&#xff0c;延时队列可以实现很多功能&#xff0c;此类业务中&#xff0c;一般上是非实时的&#xff0c;需要延迟处理的&a…

宠物品牌出海 丨战略布局这样做让你爆单不停

宠物用品市场在电商领域增长迅速。面对国内市场竞争激烈&#xff0c;同质化严重&#xff0c;不少宠物用品公司开始寻求新的市场增长点&#xff0c;将目光转向国外市场。本文将探讨宠物品牌海外扩张的商机和策略&#xff0c;以便帮助其他公司应对挑战&#xff0c;抓住国际市场的…

利用国产库libhv动手写一个web_server界面(二)

目录 一、配置参数解析与响应 1.读取参数 2.设置参数 3.恢复默认参数 二、整体的界面实现以及交互效果 三、关于yaml文件乱码问题解决 四、参考文章 一、配置参数解析与响应 使用cJSON解析库&#xff0c;解析接收到的JSON数据字段&#xff0c;区别接收到的配置参数是请…

数据结构--选择排序

1、选择排序 1.1 基本认识 1.1.1 基本概念 选择排序是一种简单直观的排序算法&#xff0c;无论什么数据进去都是 O(n) 的时间复杂度。 1.1.2 算法步骤 &#xff08;1&#xff09;首先在未排序序列中找到最小&#xff08;大&#xff09;元素&#xff0c;存放到排序序列的起…

【VTKExamples::Meshes】第十期 Decimation

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例Decimation,并解析接口vtkDecimatePro,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO…

linux项目部署 解决Nginx浏览器刷新出现404,但是不刷新是能够正常请求成功

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 提示&#xff1a;部署成功&#xff0c;访问登录页面登录也成功&#xff0c;强制刷新浏览器报404问题 进入到系统 刷新页面 解决流程 参考如图&#xff0c;再下面添加这条配置信息 location / {try_file…