首页 > 其他分享 >2.交换机与特殊队列

2.交换机与特殊队列

时间:2023-06-04 10:11:07浏览次数:48  
标签:特殊 队列 绑定 过期 交换机 消息 路由

2.交换机

2.1.类型

1.FanoutExchange(扇形)

2.DirectExchange(直连)

3.TopicExchange(主题)

4.HeadersExchange(头部)

以下类型的交换机使用都会使用到这两个步骤

①选择依赖

image-20230602232739182

②修改启动类

image-20230602232837003

2.2.FanoutExchange

2.2.1.介绍

FanoutExchange: 扇形交换机

投递到所有绑定的队列,不需要路由键,不需要进行路由键的匹配,相当于广播、群发;

fanout

2.2.2.使用

①修改配置

image-20230602233653622

②发送消息

image-20230602233709830

③绑定交换机

image-20230602233637300

2.3.DirectExchange

2.3.1.介绍

根据路由键精确匹配(一模一样)进行路由消息队列

python-four

error,info,warning称为路由key

2.3.2.使用

①修改配置类

image-20230602232757830

②发送消息类

image-20230602232855419

③绑定交换机

image-20230602233022873

④访问测试

因为绑定的是info路由,queue.direct.a是error路由,所有没有信息,而queue.direct.b绑定了三个,所以什么路由key他都可以接收到

image-20230602235944026

2.4.TopicExchange

2.4.1.介绍

只能匹配一个

通配符匹配,相当于模糊匹配;

:匹配多个单词,用来表示任意数量(零个或多个)单词

*:匹配一个单词(必须有一个,而且只有一个),用.隔开的为一个单词:

python-five

2.4.2.使用

①修改配置类

image-20230602235529990

②绑定交换机

image-20230603000059061

③发送消息

image-20230603000236818

④访问测试

发送的路由key是lazy.orange.rabbit,所有队列a和b都可以接收到,但一个队列只能接收到一个信息,所以队列b也是1条信息

image-20230603000226237

2.5.Headers Exchange (用的比较少)

2.5.1.介绍

这个是没有路由key,是由请求头进行绑定的

基于消息内容中的headers属性进行匹配

img

2.5.2.示例

绑定参考代码:

Map<String, Object> headerValues = new HashMap<>();
headerValues.put("type", "m");
headerValues.put("status", 1);
return BindingBuilder.*bind*(queueA).to(headersExchange).whereAll(headerValues).match();

发送参考代码

MessageProperties messageProperties = new MessageProperties();
messageProperties.setHeader("type", "m");
messageProperties.setHeader("status", 1);
Message message = new Message(msg.getBytes(), messageProperties);
// void convertAndSend(String exchange, String routingKey, Object message) throws AmqpException;
amqpTemplate.convertAndSend(RabbitConfig.*EXCHANGE*, null, message);

3.死信队列

3.1.介绍

一个用于存放无法被消费者处理的消息的特殊队列。当队列中的消息到达其过期时间或者出现错误时,RabbitMQ将尝试重新将该消息发送到队列中,但是如果重试次数超过阈值,则该消息将被移动到所配置的死信队列中,以便后续分析和处理。

队列的一些参数

image-20230603115823227

DLX(Dead-Letter-Exchange):死信交换器,死信邮箱

无标题

3.2.队列过期

3.2.1.项目搭建

①选择依赖

image-20230602232739182

②修改启动类

image-20230602232837003

③修改配置

image-20230603113408462

3.2.2.消费者类

image-20230603105238681

3.2.3.绑定交换机

image-20230603111435687

3.2.4.访问测试

刚打开时:正常队列是有一条信息的,20秒后,正常队列过期,变成为死信队列

image-20230603113346571

image-20230603113357365

3.3.消息过期

3.3.1.项目搭建

①选择依赖

image-20230602232739182

②修改启动类

image-20230602232837003

③修改配置

image-20230603114020293

3.3.2.消费者类

image-20230603115522914

3.3.3.绑定交换机

其他的和上面一样,只不过将这里的队列过期时间设置删除了

image-20230603115539960

3.3.4.访问测试

刚打开时:正常队列是有两条信息的,20秒后,正常队列的消息过期,变成为死信队列

注意:当队列只有一条信息,并且已经过期了,当前队列也会变成死信队列

image-20230603115349530

image-20230603115409124

3.4.队列最大长度

3.4.1.项目搭建

①选择依赖

image-20230602232739182

②修改启动类

image-20230602232837003

③修改配置

image-20230603120546907

3.4.2.消费者类

image-20230603120813411

3.4.3.绑定交换机

其他的和上面一样,这里只是添加了队列的最大长度

image-20230603120643576

3.44.4.访问测试

当正常队列超过五条信息时,其他的信息都会成为死信息

(这里有19个死信息不知道是哪里配置错了,发送了三次循坏)

image-20230603120900208

是哪五个信息是正常信息

image-20230603121211281

可以看到是先后面的五个信息是正常的信息

先进入的3个信息会成为死信息

3.5.自动确认接收消息

3.5.1.生产者搭建

image-20230603165443451

image-20230603165429670

image-20230603165454117

其他的和之前一样

3.5.2.消费者搭建

没有绑定交换机这个,其他的和上面一样

image-20230603165520758

image-20230603165528731

3.5.3.访问测试

image-20230603165615347

image-20230603165624325

可以看到正常队列和死信队列都是没有信息的,因为一发送就已经被接收并且确认了

image-20230603165708051

3.6.手动接收消息

3.6.1.手动确认接收消息

只需要修改接收消息端的部分代码即可

①修改代码

image-20230603171104198

image-20230603171055267

②访问测试

image-20230603171132811

image-20230603171143730

3.6.2.不重新投递

在接收消息这里添加一个错误

image-20230603172337140

然后进行查看

image-20230603171341919

3.6.3.重新投递

还是模拟刚才的错误,但是将是否重新投递修改为true

image-20230603172318936

此时消息就会一直进行重新投递,不会进行确认也不会变成死信息

image-20230603171517819

4.延迟队列

4.1.介绍

一种特殊的队列,它可以在到达指定的时间后将消息传递到消费者。这是通过为消息设置过期时间或 TTL(Time-to-Live)来实现的。

4.2.定时任务方式

每隔3秒扫描一次数据库,查询过期的订单然后进行处理

优点:简单,容易实现

缺点

  1. 存在延迟(延迟时间不准确),如果每隔1分钟扫一次,那么就有可能延迟1分钟;
  2. 性能较差,每次扫描数据库,如果订单量很大

4.3.被动取消

当用户查询订单的时候,判断订单是否超时,超时了就取消(交易关闭)

优点:对服务器而言,压力小

缺点

  1. 用户不查询订单,将永远处于待支付状态,会对数据统计等功能造成影响
  2. 用户打开订单页面,有可能比较慢,因为要处理大量订单,用户体验少稍差

4.4.JDK延迟队列

DelayedQueue

无界阻塞队列,该队列只有在延迟期满的时候才能从中获取元素

优点:实现简单,任务延迟低

缺点

  1. 服务重启、宕机,数据丢失
  2. 只适合单机版,不适合集群
  3. 订单量大,可能内存不足而发生异常(oom)
    • OOM(Out Of Memory)指的是操作系统或应用程序因内存耗尽导致崩溃的情况。当一个进程运行时占用了太多的内存并且没有足够的空间对其进行处理,就会产生 OOM 错误。
    • 在操作系统中,当可用内存不足时,系统会尝试通过交换(将内存中不活跃的页面移动到磁盘上)来腾出更多内存。但是,如果可用空间仍然不足或交换本身也出现问题,则可能会导致 OOM 错误。

4.5.使用消息中间件(RabbitMQ)

RabbitMQ本身不支持延迟队列,可以使用TTL结合DLX的方式来实现消息的延迟投递,即把DLX跟某个队列绑定,到了指定时间,消息过期后,就会从DLX路由到这个队列,消费者可以从这个队列取走消息。

img

这种方式有一个问题:如果先发送的消息延迟时间比后面的长,就会影响后面的延迟时间段的消息的消费

解决方法是:不同延迟时间的消息要发到不同的队列上,同一个队列的消息,它的延迟时间应该一样

img

不过写起来代码会有些繁琐,每一个不同的时间段都要创建一个不同的队列

4.6.延迟插件

rabbitmq-delayed-message-exchange

下载地址:http://www.rabbitmq.com/community-plugins.html

4.6.1.安装

在rabbitmq下的plugins目录安装插件

开启插件

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

查看插件

rabbitmq-plugins list

image-20230604092620559

4.6.2.原理

img

消息发送后不会直接投递到队列,而是存储到 Mnesia(嵌入式数据库),检查 x-delay 时间(消息头部)

延迟插件在 RabbitMQ 3.5.7 及以上的版本才支持,依赖 Erlang/OPT 18.0 及以上运行环境

Mnesia 是一个小型数据库,不适合于大量延迟消息的实现,解决了消息过期时间不一致出现的问题。

4.6.3.使用

①选择依赖

image-20230604093406204

②修改启动类

image-20230604093547484

③修改配置类

image-20230604093733484

④绑定交换机

image-20230604095014220

⑤发送消息

image-20230604100024961

⑥接收消息

image-20230604100043484

⑦访问测试

又简单又方便

image-20230604100109041

image-20230604100133120

标签:特殊,队列,绑定,过期,交换机,消息,路由
From: https://www.cnblogs.com/Myvlog/p/17455268.html

相关文章

  • 文件名特殊字符去除
    java去掉特殊字符工具类packagecom.pig4cloud.pigx.edi.utils;importjava.util.Arrays;/***文件名去掉特殊字符*/publicclassFileNameCleanerUtil{finalstaticint[]illegalChars={34,60,62,124,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,1......
  • 初级数据结构--栈、队列
    栈后端(进栈)插入,后端(出栈)删除顺序存储,用静态数组实现,需要记录栈顶指针,栈的增删操作只能操作栈顶的护数据。两种初始化方式top=-1top=0共享栈两个栈共用一片内存空间,两个栈从两边向中间增长初始化1个栈顶指针初始为-1;另一个栈顶指针初始为Maxsize栈满条件 top0+1==top1队列后端(......
  • 两个栈实现队列
    @TOC一、栈和队列的基本特点栈的特点是后进先出,而队列的特点是先进先出。使用两个栈实现队列,必须具备队列的先进先出的功能。举个例子:向其中一个栈中放入4个元素,那么按照队列的特点,出队时是1先出队,所以需要把栈的所有元素全部出栈转移到空栈中。再逐一出元素。假如出栈一次后,又需......
  • 消息队列RocketMQ基本概念
     1消息模型(MessageModel)RocketMQ主要由Producer、Broker、Consumer三部分组成,其中Producer负责生产消息,Consumer负责消费消息,Broker负责存储消息。Broker在实际部署过程中对应一台服务器,每个Broker可以存储多个Topic的消息,每个Topic的消息也可以分片存储于不......
  • 剑指 Offer 09. 用两个栈实现队列
    剑指Offer09.用两个栈实现队列</br></br>题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead操作返回-1)示例1:输入:["CQueue","appendTail",......
  • php rabbitmq队列的几种管理方案
     这里就懒得记录了,直接放上一篇还不错的知乎博主的博客吧。点击前往  ......
  • 使用两个队列实现栈
    @TOC前言本文章主要介绍栈和队列的相互转换。使用两个队列实现栈我们知道,栈的特点是后进先出,而队列的特点是先进先出。栈的特点:队列的特点:使用两个队列实现栈的思路是:1.向两个队列中的任一队列放入元素2.取出元素时,队列的功能是先进先出,要达到后进先出,需要将前面的所有元素取出,存入......
  • Java队列Disruptor 的使用
    、什么是Disruptor 从功能上来看,Disruptor是实现了“队列”的功能,而且是一个有界队列。那么它的应用场景自然就是“生产者-消费者”模型的应用场合了。可以拿JDK的BlockingQueue做一个简单对比,以便更好地认识Disruptor是什么。我们知道BlockingQueue是一个FIFO队列,生......
  • uva246 10-20-30 (双端队列deque + vector模拟)
    【题意】:一个游戏。共52张牌(1~10中的数字)。初始状态,按输入顺序放在总堆里。然后从头开始,挨着拿7张,从左到右摆开,作为7堆。然后回到第一堆,以此循环着每次往一堆放一张。每放完一张牌,考虑下面的情况:1.这一堆的头两张与尾一张之和等于10or20or302. 这一堆的头一张与尾两张之和等......
  • DC48V转5V 1A工业交换机方案芯片-AH8670C
    AH8670C是一款内部集成有功率MOSFET管可设定输出电流的降压型开关稳压器。TD:186*4884*3702*V可工作在宽输入电压范围具有优良的负载和线性调整。宽范围输入电压(8V至90V)可提供最大3A电流的高效率输出,可在移动环境输入的条件下实现各种降压型 电源 变换的应用。 安全保护机制包......