RabbitMQ工作模式(4) - 路由模式

news/2024/5/19 7:57:55

概念

路由模式(Routing)是 RabbitMQ 中的一种消息传递模式,也称为直连模式。它允许生产者将消息发送到一个交换机,并指定一个或多个路由键(routing key),交换机根据路由键将消息路由到与之匹配的队列中。这样消费者只需关注感兴趣的消息,而不需要接收所有的消息。

工作流程

  1. 生产者发送消息: 生产者将消息发送到一个交换机,并指定一个或多个路由键。

  2. 交换机根据路由键路由消息: 交换机根据消息的路由键将消息发送到与之匹配的队列中。匹配规则可以由交换机的类型和绑定规则决定。

  3. 消费者监听队列: 消费者可以选择监听特定的队列,或者多个队列,以接收他们感兴趣的消息。

  4. 消息处理: 消费者从队列中接收消息,并进行相应的处理。只有与队列绑定的交换机根据消息的路由键将消息发送到该队列中。

特点

  • 灵活路由:生产者可以根据需要指定不同的路由键来发送消息,交换机根据路由键将消息路由到不同的队列。
  • 定向传递:消息只会被发送到与之匹配的队列中,消费者只需关注他们感兴趣的消息,而不需要接收所有的消息。
  • 路由规则:可以根据实际需求定义不同的路由规则,例如根据消息的类型、内容、优先级等进行路由。

路由模式适用于需要根据不同的消息属性将消息路由到不同队列的场景,例如消息分类、事件处理、分布式系统等。

Springboot集成

1.创建队列和交换机并绑定

在RoutingConfig文件中配置

package com.model.config;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @Author: Haiven* @Time: 2024/4/22 10:09* @Description: TODO*/
@Configuration
public class RoutingConfig {/*** 路由模式交换机* @return exchange*/@Bean(name = "routingExchange")public Exchange getRoutingExchange(){return ExchangeBuilder.directExchange("exchange_routing").build();}/*** 路由队列 01* @return queue*/@Bean(name = "routingQueue01")public Queue getRoutingQueue01(){return QueueBuilder.durable("queue_routing_01").build();}/*** 路由队列 02* @return queue*/@Bean(name = "routingQueue02")public Queue getRoutingQueue02(){return QueueBuilder.durable("queue_routing_02").build();}/*** 绑定队列 01* @return binding*/@Beanpublic Binding getRoutingBinding01(){return BindingBuilder.bind(getRoutingQueue01()).to(getRoutingExchange())//路由键 队列1接收debug级别的消息.with("debug").noargs();}/*** 绑定队列 02* @return binding*/@Beanpublic Binding getRoutingBinding02(){return BindingBuilder.bind(getRoutingQueue02()).to(getRoutingExchange())// 路由键 队列2接收info级别的消息.with("info").noargs();}/*** 绑定队列 01* @return binding*/@Beanpublic Binding getRoutingBinding03(){return BindingBuilder.bind(getRoutingQueue01()).to(getRoutingExchange())//路由键 队列1接收debug级别的消息.with("err").noargs();}
}

 !!!这里创建的交换机类型为:DirectExchange,如果交换机内容错误,会导致消息错误的分发

  1. Direct Exchange(直连交换机): 直连交换机将消息的路由键与绑定队列的路由键进行精确匹配,只有当消息的路由键与绑定队列的路由键完全相同时,才会将消息路由到对应的队列。

  2. Fanout Exchange(扇出交换机): 扇出交换机将消息广播到所有与之绑定的队列,无视消息的路由键。这种模式适用于需要将消息广播给多个消费者的场景。

  3. Topic Exchange(主题交换机): 主题交换机根据消息的路由键与绑定队列的路由键进行模糊匹配,支持通配符 *#* 表示匹配一个单词,# 表示匹配零个或多个单词。这种模式适用于需要根据消息的特定属性进行路由的场景。

  4. Headers Exchange(头交换机): 头交换机根据消息的头部属性进行匹配,而不是路由键。在绑定队列时,可以指定匹配的头部属性和值,只有当消息的头部属性和值与绑定规则完全匹配时,才会将消息发送到对应的队列。

  5. Default Exchange(默认交换机): 默认交换机是 RabbitMQ 的默认交换机,它将消息的路由键与队列的名称进行匹配,如果消息的路由键与队列的名称完全匹配,则将消息路由到该队列中。默认交换机通常以空字符串表示,不需要显示声明,可以直接使用。

2.创建消费者

RoutingConsumer

package com.model.listener;import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;/*** @Author: Haiven* @Time: 2024/4/22 10:08* @Description: TODO*/
@Component
public class RoutingConsumer {@RabbitListener(queues = {"queue_routing_01"})public void routingConsumer01(String msg){System.out.println("消费者 -01- 接收消息:" + msg);}@RabbitListener(queues = {"queue_routing_02"})public void routingConsumer02(String msg){System.out.println("消费者 -02- 接收消息:" + msg);}
}

3.创建生产者并发送消息

package com.model.controller;import com.code.domain.Response;
import com.model.service.RabbitService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** @Author: Haiven* @Time: 2024/4/19 9:46* @Description: TODO*/
@RestController
@RequestMapping("/producer")
public class ProducerController {@Resourceprivate RabbitService rabbitService;@GetMapping("/simple")public Response<Void> simple(String msg){boolean res = rabbitService.simple(msg);return res ? Response.success() : Response.fail();}@GetMapping("/work")public Response<Void> work(String msg){boolean res = rabbitService.work(msg);return res ? Response.success() : Response.fail();}@GetMapping("/sub")public Response<Void> sub(String msg){boolean res = rabbitService.sub(msg);return res ? Response.success() : Response.fail();}@GetMapping("/routing")public Response<Void> routing(String msg, String type){boolean res = rabbitService.routing(msg, type);return res ? Response.success() : Response.fail();}
}
package com.model.service.impl;import com.model.service.RabbitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** @Author: Haiven* @Time: 2024/4/19 10:51* @Description: TODO*/
@Service
@Slf4j
public class RabbitServiceImpl implements RabbitService {@Resourceprivate RabbitTemplate rabbitTemplate;@Value("${rabbitmq.simple.queue}")private String simpleQueue;@Value("${rabbitmq.work.queue}")private String workQueue;@Overridepublic boolean simple(String msg) {try {rabbitTemplate.convertAndSend(simpleQueue, msg);return true;}catch (Exception e){e.printStackTrace();return false;}}@Overridepublic boolean work(String msg) {try {rabbitTemplate.convertAndSend(workQueue, msg);return true;}catch (Exception e){e.printStackTrace();return false;}}@Overridepublic boolean sub(String msg) {try {//路由模式就不能直接发送消息到队列了, 而是发送到交换机,由交换机进行广播, routingKey为路由Key 订阅模式给""rabbitTemplate.convertAndSend("exchange_sub","", msg);return true;}catch (Exception e){e.printStackTrace();return false;}}@Overridepublic boolean routing(String msg, String type) {System.out.println("理由模式发送消息:msg="+msg+",type="+type+"");try {//路由模式就不能直接发送消息到队列了, 而是发送到交换机,由交换机进行广播, routingKey为路由Key 订阅模式给""rabbitTemplate.convertAndSend("exchange_routing",type, msg);return true;}catch (Exception e){e.printStackTrace();return false;}}
}

4.发送消息

接口调用发送消息, type字段为消息的级别

 后台接收

 debug级别消息只被消费者1消费

 info级别的消息只被消费者2消费

5.额外说明

上述消费者1只消费了debug级别,如果还有err级别的消息,只需在将队列1绑定err级别的消息

  /*** 绑定队列 01* @return binding*/@Beanpublic Binding getRoutingBinding03(){return BindingBuilder.bind(getRoutingQueue01()).to(getRoutingExchange())//路由键 队列1接收debug级别的消息.with("err").noargs();}

发送消息并测试

 如果某种消息级别(warn)没有被绑定,这该级别的消息会被丢弃

 


http://www.mrgr.cn/p/41525435

相关文章

leetcode(力扣) 2866. 美丽塔 II

原题链接 暴力做法 (时间复杂度 O(n^2)) 每次选取下标 i 为峰值, 进行 n 次,对每次取max就可以找打答案对于 i 左边的序列: 需要满足序列是非递减的, 同时每个值尽可能大 所以满足: 下标为 j 的位置上的数 <= 下标是 (j, i] 的最小的值 (等于时取得最大值) , 同时需要保证…

科技感十足特效源码

源码介绍 科技感十足特效源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 源码截图 源码下载 科技感十足特效源码

CCS项目持续集成

​ 因工作需要&#xff0c;用户提出希望可以做ccs项目的持续集成&#xff0c;及代码提交后能够自动编译并提交到svn。调研过jenkins之后发现重新手写更有性价比&#xff0c;所以肝了几晚终于搞出来了&#xff0c;现在分享出来。 ​ 先交代背景&#xff1a; 1. 代码分两部分&am…

在微信上卖化妆品怎样发圈(学会写朋友圈段子卖货很简单)

大家好&#xff0c;我是只说人话&#xff0c;不讲概念&#xff0c;专给创业者们开思维脑洞 今天咱们要分享的内容比较有趣&#xff0c;教你如何写段子故事在朋友圈里做促销活动。 首先我们来看一个硬蹭明星热点的朋友圈案例。发朋友圈的是一位做装修的&#xff0c;在明星结婚的…

基于CANoe从零创建以太网诊断工程(2)—— TCP/IP Stack 配置的三种选项

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

云渲染一张图多少钱

使用云渲染渲染一张效果图的价格没法确定多少钱一张&#xff0c;云渲染一张图的价格会受到多个因素的影响&#xff0c;如云渲染平台的定价策略、所选的渲染配置、优惠政策以及你提交的场景任务等。因此&#xff0c;无法给出确切的单一价格。 不同的云渲染平台会有不同的定价模…

《深入浅出.NET框架设计与实现》笔记2——C#源码从编写到执行的流程

中间语言&#xff08;Intermediate Language&#xff0c;IL&#xff09; C#编译器在编译时&#xff0c;会将源代码作为输入&#xff0c;并以中间语言形式输入出&#xff0c;该代码保存在*.exe文件中或*.dll文件中。 公共语言运行时&#xff08;CLR&#xff09; 可以将IL代码…

【java、微服务】MQ

MQ(MessageQueue)&#xff0c;中文是消息队列&#xff0c;字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。 同步通讯 优点 时效性较强&#xff0c;可以立即得到结果 问题 微服务间基于Feign的调用就属于同步方式&#xff0c;存在一些问题。 耦合度高。每次加…

中科院笔试考试结束

2024-04-28 22:03:11 星期日 周四的下午三点五十,我收到了中科院的笔试通知,但是考试时间是本周日,也就是说我只有三天时间复习早就忘掉的数分高代,备考压力绝不亚于从零开始七天准备高考\(\ldots\)三天几乎泡在图书馆挑着重点过一遍知识,级数、重积分、反常积分等等连翻都…

Transition

内置组件Transition官网详细文档:https://cn.vuejs.org/v2/guide/transitions.html时机 Transition组件会监控slot中唯一根元素的出现和消失,并会在其出现和消失时应用过渡效果 具体的监听内容是:它会对新旧两个虚拟节点进行对比,如果旧节点被销毁,则应用消失效果,如果新…

TechTool Pro for mac中文激活版:硬件监测和系统维护工具

TechTool Pro mac帮助用户实现系统硬件监测&#xff08;CPU、内存、硬盘、网络、USB等&#xff09;、内存测试、S.M.A.R.T检测、磁盘宗卷扫描、宗卷重建和优化、数据恢复和粉碎等等&#xff0c;定期使用&#xff0c;可以确保您的Mac保持优化和无故障。 TechTool Pro for mac v1…

JavaEE初阶——多线程(六)——线程池

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享多线程的第六篇文章,关于线程池 如果有不足的或者错误的请您指出! 目录 3.线程池3.1标准库的线程池3.2 标准库自己提供的几个工厂类3.3自己实现一个线程池完成大体框架接下来完…

FPGA 以太网通信UDP通信环回

1 实验任务 上位机通过网口调试助手发送数据给 FPGA &#xff0c; FPGA 通过 PL 端以太网接口接收数据并将接收到的数据发送给上位机&#xff0c;完成以太网 UDP 数据的环回。 2 系统设计 系统时钟经过PLL时钟模块后&#xff0c;生成了两种不同频率和相位的时钟信号&#…

实验三—软件测试

一、实验题目 :软件测试 二、实验目的 1、熟悉开发环境下的自动化测试工具; 1、利用自动化测试工具进行自动化单元测试。 三、实验内容 1、选择开发环境,IDEA或PYCHARM任选其一; 2、基于所选择的开发环境实现对输入的n个整数进行排序的代码; 3、对所编写代码设计测试用例;…

知网怎么查重 知网查重的详细步骤

知网查重八个步骤&#xff1a;1. 访问官网&#xff0c;注册账号。2. 上传待查文档。3. 选择查重规则。4. 选择相似来源库。5. 提交查重任务。6. 等待查重结果。7. 获取查重报告。8. 下载查重报告。 知网查重的详细步骤 第一步&#xff1a;进入知网查重系统 打开浏览器&#x…

生命周期

创建vue实例和创建组件的流程基本一致首先做一些初始化的操作,主要是设置一些私有属性到实例中运行生命周期钩子函数****beforeCreate进入注入流程:处理属性、computed、methods、data、provide、inject,最后使用代理模式将它们挂载到实例中运行生命周期钩子函数****created…

diff

diff的时机 当组件创建时,以及依赖的属性或数据变化时,会运行一个函数,该函数会做两件事:运行_render生成一棵新的虚拟dom树(vnode tree) 运行_update,传入虚拟dom树的根节点,对新旧两棵树进行对比,最终完成对真实dom的更新核心代码如下:// vue构造函数 function Vue…

D - Grid and Magnet

D - Grid and Magnet https://atcoder.jp/contests/abc351/tasks/abc351_d思路 定义输入矩阵元素值s matrix each cell can have three possible values: 0 - emtpy and not magnet field 1 - magnet 2 - magnet field 输入的时候,只标记 0 1 然后遍历 所…

日志分析-redis应急响应

简介 服务器场景操作系统 Linux 服务器账号密码 root xjredis 任务环境说明 注:样本请勿在本地运行!!!样本请勿在本地运行!!!样本请勿在本地运行!!! 应急响应工程师小王某人收到安全设备告警服务器被植入恶意文件,请上机排查步骤#1通过本地 PC SSH到服务器并且分析黑…