RabbitMQ_五种模式

news2024/11/26 20:23:45

1.Simple("Hello World")

构成:生产者、消费者、消息队列 

配置类

构造函数参数:name durable exclusive autoDelete

仅创建队列,不创建交换机,也不进行队列和交换机的绑定

注:配置类置于生产者端或消费者端无硬性要求,但置于消费者端更有利于测试代码,原因如下:

若先启动生产者端发送消息,再启动消费者端接收消息,则最先连接到RabbitMQ服务器的消费者将接收所有的消息,所以通常而言需要先启动消费者端;而先启动消费者端时,若将配置类置于生产者端,则可能会出现消费者端中使用,但尚未被配置到RabbitMQ的配置(若配置类在生产者端的话),所以将配置类置于消费者端更有利于测试代码,另外,在项目启动时就进行配置显然是很好的选择

@Configuration
public class HelloWorldConfiguration {
    // 创建消息队列
    // 不需要交换机(使用默认交换机direct)
    @Bean
    public Queue helloWorldQueue(){
        return new Queue("hello_world_queue", true, false, false);
    }
}

生产者

convertAndSend方法参数:exchange routingKey message

默认交换机为direct交换机,将routingKey设置为队列名可将消息直接发送至该队列

@Service
public class SayHelloWorldService {
    @Autowired
    RabbitTemplate rabbitTemplate;

    public void say(){
        rabbitTemplate.convertAndSend("", "hello_world_queue", "hello, world");
        System.out.println("消息发送成功");
    }
}

消费者

@RabbitListener 监听队列

@RabbitHandler 消息处理

@Service
@RabbitListener(queues = "hello_world_queue")
public class HelloWorldService {

    @RabbitHandler
    public void message(String message){
        System.out.println("消息: " + message);
    }
}

测试

    @Autowired
    SayHelloWorldService sayHelloWorldService;
    @Test
    void helloWorld(){
        sayHelloWorldService.say();
    }

 

2.Work Queues(工作模式)

构成:生产者、消费者、消息队列(较Simple模式而言,存在多个消费者)

配置类

@Configuration
public class WorkQueuesConfiguration {
    // 创建消息队列
    // 不需要交换机(使用默认交换机direct)
    @Bean
    public Queue workQueue(){
        return new Queue("work_queue", true, false, false);
    }
}

生产者

@Service
public class WorkQueuesService {
    @Autowired
    RabbitTemplate rabbitTemplate;

    public void workQueues(String message){
        rabbitTemplate.convertAndSend("", "work_queue", message);
        System.out.println("消息发送完成");
    }
}

消费者 

@Service
@RabbitListener(queues = "work_queue")
public class Worker01Service {

    @RabbitHandler
    public void worker01(String message){
        System.out.println("Worker01收到消息: " + message);
    }
}
@Service
@RabbitListener(queues = "work_queue")
public class Worker02Service {

    @RabbitHandler
    public void worker01(String message){
        System.out.println("Worker02收到消息: " + message);
    }
}
@Service
@RabbitListener(queues = "work_queue")
public class Worker03Service {

    @RabbitHandler
    public void worker03(String message){
        System.out.println("Worker03收到消息: " + message);
    }
}

测试 

可以看到消息被平分给了三个消费者

 

3.Publish/Subscribe(发布/订阅模式)

构成:生产者、消费者、消息队列、fanout交换机

相较于上述模式,区别在于具有自定义的交换机,类型为fanout

配置类

将消息队列与交换机进行绑定,当有生产者向交换机投递消息时,交换机将会把消息转发至所有与其绑定的消息队列

@Configuration
public class FanoutConfiguration {

    //订单交换机
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("fanout_exchange_order", true, false);
    }

    //消息通知队列(短信与邮件)
    @Bean
    public Queue fanoutSMSQueue(){
        return new Queue("sms_queue", true, false, false);
    }
    @Bean
    public Queue fanoutEmailQueue(){
        return new Queue("email_queue", true, false, false);
    }

    //绑定交换机与队列
    @Bean
    public Binding fanoutSMSBinding(){
        return BindingBuilder.bind(fanoutSMSQueue()).to(fanoutExchange());
    }
    @Bean
    public Binding fanoutEmailBinding(){
        return BindingBuilder.bind(fanoutEmailQueue()).to(fanoutExchange());
    }
}

生产者

此处routingKey为空(fanout交换机无需routingKey)

@Service
public class FanoutOrderService {
    @Autowired
    RabbitTemplate rabbitTemplate;

    public void makeOrder(String userID, String producerID, int num){
        // 1.根据需求查询仓库 判断是否能满足需求

        // 2.若能满足则生成订单
        String orderID = UUID.randomUUID().toString();
        System.out.println("成功生成订单");

        // 3.通过RabbitMQ发送消息
        String exchangeName = "fanout_exchange_order";
        String routingKey = "";
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderID);
        System.out.println("订单发送成功");
    }
}

消费者

@Service
// @RabbitListener 监听消息队列
@RabbitListener(queues = "email_queue")
public class EmailMessageService {

    // @RabbitHandler 消息处理(接收消息)
    @RabbitHandler
    public void receiveEmailMessage(String message){
        System.out.println("接收到Email消息: " + message);
    }
}
@Service
// @RabbitListener 监听消息队列
@RabbitListener(queues = "sms_queue")
public class SMSMessageService {

    // @RabbitHandler 消息处理(接收消息)
    @RabbitHandler
    public void receiveSMSMessage(String message){
        System.out.println("接收到SMS消息: " + message);
    }
}

测试 

    @Autowired
    FanoutOrderService fanoutOrderService;
    @Test
    void fanoutOrder() {
        fanoutOrderService.makeOrder("1", "1", 1);
    }

 

4.Routing(路由模式)

构成:生产者、消费者、消息队列、direct交换机

相较于Publish/Subscribe模式,区别在于交换机类型,direct交换机支持以routingKey标识并分类消息队列

配置类

绑定消息队列与交换机时,还需要绑定routingKey,交换机将根据routingKey标识并分类消息队列;发送消息时,需要指明routingKey,交换机会根据routingKey将消息转发至对应的消息队列处

@Configuration
public class DirectConfiguration {

    //订单交换机
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("direct_exchange_order", true, false);
    }

    //消息通知队列(短信与邮件)
    @Bean
    public Queue directSMSQueue(){
        return new Queue("sms_queue", true, false, false);
    }
    @Bean
    public Queue directEmailQueue(){
        return new Queue("email_queue", true, false, false);
    }

    //绑定交换机与队列
    @Bean
    public Binding directSMSBinding(){
        return BindingBuilder.bind(directSMSQueue()).to(directExchange()).with("sms");
    }
    @Bean
    public Binding directEmailBinding(){
        return BindingBuilder.bind(directEmailQueue()).to(directExchange()).with("email");
    }
}

生产者

此处需要指明routingKey

@Service
public class DirectOrderService {
    @Autowired
    RabbitTemplate rabbitTemplate;

    public void makeOrder(String userID, String producerID, int num){
        // 1.根据需求查询仓库 判断是否能满足需求

        // 2.若能满足则生成订单
        String orderID = UUID.randomUUID().toString();
        System.out.println("成功生成订单");

        // 3.通过RabbitMQ发送消息
        String exchangeName = "direct_exchange_order";
        String routingKey01 = "sms";
        String routingKey02 = "email";
        rabbitTemplate.convertAndSend(exchangeName, routingKey01, orderID + " sms");
        rabbitTemplate.convertAndSend(exchangeName, routingKey02, orderID + " email");
        System.out.println("订单发送成功");
    }
}

 消费者

@Service
// @RabbitListener 监听消息队列
@RabbitListener(queues = "email_queue")
public class EmailMessageService {

    // @RabbitHandler 消息处理(接收消息)
    @RabbitHandler
    public void receiveEmailMessage(String message){
        System.out.println("接收到Email消息: " + message);
    }
}
@Service
// @RabbitListener 监听消息队列
@RabbitListener(queues = "sms_queue")
public class SMSMessageService {

    // @RabbitHandler 消息处理(接收消息)
    @RabbitHandler
    public void receiveSMSMessage(String message){
        System.out.println("接收到SMS消息: " + message);
    }
}

​​​​​​​测试

    @Autowired
    DirectOrderService directOrderService;
    @Test
    void directOrder() {
        directOrderService.makeOrder("1", "1", 1);
    }

 

5.Topic(主题模式)

构成:生产者、消费者、消息队列、topic交换机

相较于Routing模式,区别在于交换机类型,topic交换机可模糊匹配routingKey

关于模糊匹配规则

* 表示仅一级 #表示零级或多级(以.分级 级的内容可以为空)
举例:队列1 2的routing key分别为 *.number.* 与 #.number.#
   x.number.y 将匹配队列1 2
   .number. 将匹配队列2
   x.number. 将匹配队列2
   .number.y 将匹配队列2

配置类

此处routingKey以模糊匹配规则定义

@Configuration
public class TopicConfiguration {

    //订单交换机
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange("topic_exchange_order", true, false);
    }

    //消息通知队列(短信与邮件)
    @Bean
    public Queue topicSMSQueue(){
        return new Queue("sms_queue", true, false, false);
    }
    @Bean
    public Queue topicEmailQueue(){
        return new Queue("email_queue", true, false, false);
    }

    //绑定交换机与队列
    @Bean
    public Binding topicSMSBinding(){
        return BindingBuilder.bind(topicSMSQueue()).to(topicExchange()).with("*.sms.*");
    }
    @Bean
    public Binding topicEmailBinding(){
        return BindingBuilder.bind(topicEmailQueue()).to(topicExchange()).with("#.email.#");
    }
}

生产者

@Service
public class TopicOrderService {
    @Autowired
    RabbitTemplate rabbitTemplate;

    public void makeOrder(String userID, String producerID, int num){
        // 1.根据需求查询仓库 判断是否能满足需求

        // 2.若能满足则生成订单
        String orderID = UUID.randomUUID().toString();
        System.out.println("成功生成订单");

        // 3.通过RabbitMQ发送消息
        String exchangeName = "topic_exchange_order";
        String routingKey01 = "xxx.sms.yyy";
        String routingKey02 = ".email.";
        rabbitTemplate.convertAndSend(exchangeName, routingKey01, orderID + " sms");
        rabbitTemplate.convertAndSend(exchangeName, routingKey02, orderID + " email");
        System.out.println("订单发送成功");
    }
}

 消费者

@Service
// @RabbitListener 监听消息队列
@RabbitListener(queues = "email_queue")
public class EmailMessageService {

    // @RabbitHandler 消息处理(接收消息)
    @RabbitHandler
    public void receiveEmailMessage(String message){
        System.out.println("接收到Email消息: " + message);
    }
}
@Service
// @RabbitListener 监听消息队列
@RabbitListener(queues = "sms_queue")
public class SMSMessageService {

    // @RabbitHandler 消息处理(接收消息)
    @RabbitHandler
    public void receiveSMSMessage(String message){
        System.out.println("接收到SMS消息: " + message);
    }
}

测试

可以看到,模糊匹配成功

 

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

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

相关文章

如何处理 Angular 单页面应用里的 a 标签,避免点击后重新加载整个应用

问题描述 客户已经实现了一些“free html”组件&#xff0c;它是 HTML 的标题和包装器&#xff0c;与 OCC 响应一起作为内容。 <div [innerHTML]"data?.content | safeHtml"></div>这个 HTML 里包含了 anchor element&#xff1a; <div class&quo…

Linux源码——目录作用

Linux Linux是啥&#xff0c;不用多说&#xff0c;其源码结构也非常清晰。有以下理解&#xff1a; arch 每个系列的CPU都有一个对应的文件夹&#xff0c;里面包含每种CPU具体的操作&#xff0c;单独具体粗来每种CPU独有的管理或者操作。其他的文件夹都是通用的操作。 arch (…

孤核函数-isolation kernel

1.孤立核 一看到核函数&#xff0c;我们第一时间想到的就是核函数通过升维或者降维的方式来计算数据之间的相似度。他在SVM和聚类算法中应用广泛。 我们就直入主题来看一下孤核函数的数学推导。 在d维的空间分布着n个点。数学表达式为. 如图&#xff1a;一共20个点分布在2维空间…

浅析linux内核网络协议栈--linux bridge

1 . 前言 本文是参考附录上的资料整理而成&#xff0c;以帮助读者更好的理解kernel中brdige 模块代码。 2. 网桥的原理 2.1 桥接的概念 简单来说&#xff0c;桥接就是把一台机器上的若干个网络接口“连接”起来。其结果是&#xff0c;其中一个网口收到的报文会被复制给其他…

深入了解BLE(Bluetooth 5.3)持续更新...

目录 1 BLE的优点和局限性 1.1 BLE与经典蓝牙的区别 1.2 局限性 1.2.1 数据吞吐量 1.2.2 范围 1.3 BLE优势及应用 1.4 BLE的角色 1.5 BLE的层次结构 1.5.1 物理层&#xff08;PHY&#xff09; 1.5.2 链路层 1.5.2.1 数据包格式 1.5.2.2 状态机 1.5.2.3 设备地址 …

PTA_1164 Good in C_模拟

PTA_1164 Good in C_模拟 1164 Good in C 分数 20 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 When your interviewer asks you to write "Hello World" using C, can you do as the following figure shows? Input Specification: Each input file conta…

STM32实战总结:HAL之FSMC控制TFT-LCD

什么是FSMC&#xff1f; FSMC(Flexible Static Memory Controller&#xff0c;可变静态存储控制器)是STM32系列采用的一种新型的存储器扩展技术。在外部存储器扩展方面具有独特的优势&#xff0c;可根据系统的应用需要&#xff0c;方便地进行不同类型大容量静态存储器的扩展。 …

计算机网络 HTTP

概念 Web 基础 HTTP &#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;。WWW &#xff08;World Wide Web&#xff09;的三种技术&#xff1a;HTML、HTTP、URL。RFC&#xff08;Request for Comments&#xff0c;征求意见书&#xff09;&#…

HTTP DDOS攻击有什么类型和特点?

一、攻击类型 1、 HTTP floods 该攻击类型分为HTTP GET request floods和HTTP POST request floods两种形式&#xff0c;第一种攻击者通过构造HTTP GET请求报文&#xff0c;向目标服务器发送针对特定资源的大量请求&#xff1b;一条HTTP请求的成本很低&#xff0c;但是目标服…

力扣(LeetCode)124. 二叉树中的最大路径和(C++)

深度优先遍历 自底向上的递归。 对于二叉树&#xff0c;我们令每个结点作为 LCALCALCA (最近公共祖先)&#xff0c; 结点 uuu 作为 LCALCALCA &#xff0c; 经过它的最大路径 往左子树的最大路径 往右子树的最大路径 它自己的路径 。 有 ansmax(ans,vulrans max(ans,v_ul…

MobPush 厂商通道SDK集成指南

开发工具&#xff1a;Android Studio 集成方式&#xff1a;Gradle在线集成 安卓版本支持&#xff1a;minSdkVersion 19 集成准备 MobPush快速集成 在使用厂商通道之前&#xff0c;请确保您已申请MobTech开发者账号并已按照MobPush快速集成文档进行集成&#xff0c;本篇文档将…

POI实现Excel导入和导出(源码测试)

因为实际开发中很多需求都需要实现Excel批量导入和导出&#xff0c;所以今天就来写一个后端demo实现Excel的导入和导出。 需求&#xff1a; Excel的导入 1对文件路径为D:\Users\Mixi\IdeaProjects\javapoi-anli\product-test.xlsx 的Excel文件导入到数据库&#xff1b; Excel的…

SAP 采购订单免费标识自动勾选的判断依据

SAP采购订单的免费标识没有专门的字段存储,是根据发票收据和项目类别计算出来的 写程序的时候折磨判断呢? 1.EKPO-REPOS <> ‘X’ AND EKPO-PSTYP <> ‘2’ AND EKPO-PSTYP <> ‘7’ &#xff0c;则系统会自动勾选上这个免费项目 2.如果要求不是很精密&…

机器学习之MATLAB代码--LSTM-SVRNN(五)

机器学习之MATLAB代码--LSTM-SVRNN&#xff08;五&#xff09;代码数据结果代码 1、cdmnn.m文件 %% 组合模型 %% %% 数据导入 clc;clear;warning off; data xlsread(nndata.xlsx, sheet1, A2:G350); load LSTMoutput load SVMoutput %% nwholelength(data); %计算数据长度…

Vue笔记_transition组件(过渡样式)

目录transition组件作用过渡时机语法1语法2使用-animation侦动画使用-过渡动画总结transition组件 作用 transition组件的作用是 给 单个 元素/组件 添加过渡效果&#xff1b; transition-group组件的作用是给 多个 元素/组件 添加过渡效果&#xff1b; 过渡时机 vue只有在…

【pen200-lab】10.11.1.13

pen200-lab 学习笔记 【pen200-lab】10.11.1.13 &#x1f525;系列专栏&#xff1a;pen200-lab &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月30日&#x1f334; &#x1f36d;作…

turtlebot2利用turtlebot_exploration_3d进行自主建图

安装octomap_ros和rviz插件 sudo apt-get install ros-indigo-octomap*源码安装&#xff1a;turtlebot_exploration_3d(本机为Ubuntu16对应的ros版本为kinetic&#xff0c;但是无对应的版本&#xff0c;用的是ubuntu14的indigo&#xff0c;版本向前兼容&#xff0c;故可以运行&…

AXWWriter兼容的Word处理元素

AXWWriter兼容的Word处理元素 AXWWriter是一个与MS Word兼容的Word处理元素。该部件不需要设置任何其他库或软件。 AXWWriter使用DOCXReadWrite一起工作,DOCXReadWriter也包含在内。有关其他属性,请查看DOCXReadWrite。AXWWriter不难使用。如果您了解DOCXReadWrite,那么您已…

岩藻多糖-聚已内酯 Fucoidan-PCL 聚已内酯-PEG-岩藻多糖

岩藻多糖-聚已内酯 Fucoidan-PCL 聚已内酯-PEG-岩藻多糖 中文名称&#xff1a;岩藻多糖-聚已内酯 英文名称&#xff1a;Fucoidan-PCL 别称&#xff1a;PCL修饰岩藻多糖&#xff0c;PCL-岩藻多糖 聚己内酯&#xff08;Polycaprolactone&#xff0c;PCL&#xff0c;CAS号…

第4部分 RIP

动态路由协议包括距离向量路由协议和链路状态路由协议。RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是使用最广泛的距离微向量路由协议。RIP 是为小型网络环境设计的&#xff0c;国为这类协议是路由学习及路由更新将产生较大的流量&…