RabbitMQ学习05

文章目录

    • 交换机
      • 1.Exchanges
        • 1.1 概念
        • 1.2 类型
        • 1.3 无名exchange
      • 2. 临时队列
      • 3. 绑定(bings)
      • 4. Fanout
        • 4.1 介绍
      • 5.Direct exchange
        • 5.1 介绍
        • 5.2 多重绑定
        • 5.3 实战:
      • 6. Topics
        • 6.1 规则
        • 6.2 实战

交换机

1.Exchanges

1.1 概念

    RabbitMQ 消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上,通常生产者甚至都不知道这些消息传递传递到了哪些队列中。
    相反,生产者只能将消息发送到交换机(exchange),交换机工作的内容非常简单,一方面它接收来自生产者的消息,另一方面将它们推入队列。交换机必须确切知道如何处理收到的消息。是应该把这些消息放到特定队列还是说把他们到许多队列中还是说应该丢弃它们。这就的由交换机的类型来决定。
在这里插入图片描述

1.2 类型
  1. 直接(direct)
  2. 主题(topic)
  3. 标题(header)
  4. 扇出(fanout)
1.3 无名exchange

    第一个参数是交换机的名称。空字符串表示默认或无名称交换机:消息能路由发送到队列中其实是由 routingKey(bindingkey)绑定 key 指定的,如果它存在的话

2. 临时队列

    队列的名称我们来说至关重要-我们需要指定我们的消费者去消费哪个队列的消息。
每当我们连接到 Rabbit 时,我们都需要一个全新的空队列,为此我们可以创建一个具有随机名称的队列,或者能让服务器为我们选择一个随机队列名称那就更好了。其次一旦我们断开了消费者的连接,队列将被自动删除
创建临时队列的方式如下:

String queueName = channel.queueDeclare().getQueue();

3. 绑定(bings)

    binding 其实是 exchange 和 queue 之间的桥梁,它告诉我们 exchange 和那个队列进行了绑定关系。比如说下面这张图告诉我们的就是 X 与 Q1 和 Q2 进行了绑定。在这里插入图片描述

4. Fanout

4.1 介绍

    Fanout 这种类型非常简单。正如从名称中猜到的那样,它是将接收到的所有消息广播到它知道的所有队列中。系统中默认有些 exchange 类型
在这里插入图片描述

在这里插入图片描述
ReceiveLogs01 将接收到的消息打印在控制台

public class ReceiveLogs01 {
    //交换机名称
    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {

        Channel channel = RabbitMQUtils.getChannel();
        //声明一个交换机
        channel.exchangeDeclare(EXCHANGE_NAME,"fanout");
        //声明一个队列 临时队列
        /**
         * 生成一个临时队列,队列的名称是随机的
         * 当消费者断开与队列的连接时 队列就会自动删除
         */
        String queueName = channel.queueDeclare().getQueue();
        /**
         * 绑定交换机与队列
         */
        channel.queueBind(queueName,EXCHANGE_NAME,"");
        System.out.println("等待接收消息,把接受的消息打印在屏幕上.......");

        //接收消息
        DeliverCallback deliverCallback = (consumerTag, message) ->{
            System.out.println("ReceiveLogs01控制台打印接受的消息:" + new String(message.getBody(), StandardCharsets.UTF_8));
        };

        channel.basicConsume(queueName,true,deliverCallback,consumerTag -> {});
    }
}

ReceiveLogs02 将接收到的消息打印在控制台

public class ReceiveLogs02 {

    //交换机名称
    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {

        Channel channel = RabbitMQUtils.getChannel();
        //声明一个交换机
        channel.exchangeDeclare(EXCHANGE_NAME,"fanout");
        //声明一个队列 临时队列
        /**
         * 生成一个临时队列,队列的名称是随机的
         * 当消费者断开与队列的连接时 队列就会自动删除
         */
        String queueName = channel.queueDeclare().getQueue();
        /**
         * 绑定交换机与队列
         */
        channel.queueBind(queueName,EXCHANGE_NAME,"");
        System.out.println("等待接收消息,把接受的消息打印在屏幕上.......");

        //接收消息
        DeliverCallback deliverCallback = (consumerTag,message) ->{
            System.out.println("ReceiveLogs02控制台打印接受的消息:" + new String(message.getBody(), StandardCharsets.UTF_8));
        };

        channel.basicConsume(queueName,true,deliverCallback,consumerTag -> {});
    }
}

EmitLog 发送消息给两个消费者接收

public class EmitLog {
    //交换机名称
    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMQUtils.getChannel();
        //声明一个交换机
        channel.exchangeDeclare(EXCHANGE_NAME,"fanout");

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            String message = scanner.next();
            channel.basicPublish(EXCHANGE_NAME,"",null,message.getBytes(StandardCharsets.UTF_8));
            System.out.println("生产者发出消息:" + message);
        }
    }
}

5.Direct exchange

5.1 介绍

    上一节中的我们的日志系统将所有消息广播给所有消费者,对此我们想做一些改变,例如我们希望将日志消息写入磁盘的程序仅接收严重错误(errros),而不存储哪些警告(warning)或信息(info)日志消息避免浪费磁盘空间。Fanout 这种交换类型并不能给我们带来很大的灵活性-它只能进行无意识的广播,在这里我们将使用 direct 这种类型来进行替换,这种类型的工作方式是,消息只去到它绑定的routingKey 队列中去
在这里插入图片描述
    在上面这张图中,我们可以看到 X 绑定了两个队列,绑定类型是 direct。队列 Q1 绑定键为 orange,队列 Q2 绑定键有两个:一个绑定键为 black,另一个绑定键为 green.
在这种绑定情况下,生产者发布消息到 exchange 上,绑定键为 orange 的消息会被发布到队列Q1。绑定键为 blackgreen 和的消息会被发布到队列 Q2,其他消息类型的消息将被丢弃。

5.2 多重绑定

在这里插入图片描述
    当然如果 exchange 的绑定类型是 direct,但是它绑定的多个队列的 key 如果都相同,在这种情况下虽然绑定类型是 direct 但是它表现的就和 fanout 有点类似了,就跟广播差不多,如上图所示。

5.3 实战:
public class ReceiveLogsDirect01 {

    public static final String EXCHANGE_NAME = "direct_logs";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQUtils.getChannel();
        //声明一个交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        //声明一个队列
        channel.queueDeclare("console", false,false,false,null);

        channel.queueBind("console",EXCHANGE_NAME,"info");
        channel.queueBind("console",EXCHANGE_NAME,"warning");

        DeliverCallback deliverCallback = (consumerTag, message) ->{
            System.out.println("ReceiveLogsDirect01:" + new String(message.getBody(), StandardCharsets.UTF_8));
        };

        channel.basicConsume("console",true,deliverCallback,consumerTag -> {});


    }

}
public class ReceiveLogsDirect02 {

    public static final String EXCHANGE_NAME = "direct_logs";

    public static void main(String[] args) throws Exception{
        Channel channel = RabbitMQUtils.getChannel();
        //声明一个交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        //声明一个队列
        channel.queueDeclare("disk", false,false,false,null);

        channel.queueBind("disk",EXCHANGE_NAME,"error");

        DeliverCallback deliverCallback = (consumerTag, message) ->{
            System.out.println("ReceiveLogsDirect02:" + new String(message.getBody(), StandardCharsets.UTF_8));
        };

        channel.basicConsume("disk",true,deliverCallback,consumerTag -> {});


    }

}
public class DirectLogs {
    //交换机名称
    public static final String EXCHANGE_NAME = "direct_logs";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMQUtils.getChannel();
        //声明一个交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            String message = scanner.next();
            channel.basicPublish(EXCHANGE_NAME,"error",null,message.getBytes(StandardCharsets.UTF_8));
            System.out.println("生产者发出消息:" + message);
        }
    }
}

测试结果:
    routingkey指定给哪个交换机,

6. Topics

6.1 规则

    发送到类型是 topic 交换机的消息的 routing_key 不能随意写,必须满足一定的要求,它必须是一个单词列表,以点号分隔开。这些单词可以是任意单词,比如说:“stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”.这种类型的。当然这个单词列表最多不能超过 255 个字节。
    在这个规则中,有两个替换符需要注意
*(星号)可以代替一个单词
#(井号)可以替代零个或多个单词
    当队列绑定关系是下列这种情况时需要引起注意:
当一个队列绑定键是#,那么这个队列将接收所有数据,就有点像 fanout 了
如果队列绑定键当中没有#和*出现,那么该队列绑定类型就是 direct 了
=

6.2 实战
public class EmitLogTopic {

    public static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] args) throws Exception{

        Channel channel = RabbitMQUtils.getChannel();

        Map<String,String> bingKeyMap = new HashMap<>();
        bingKeyMap.put("quick.orange.rabbit","被队列 Q1Q2 接收到");
        bingKeyMap.put("azy.orange.elephant","被队列 Q1Q2 接收到");
        bingKeyMap.put("quick.orange.fox","被队列 Q1 接收到");
        bingKeyMap.put("lazy.brown.fox","被队列 Q2 接收到");
        bingKeyMap.put("azy.pink.rabbit","虽然满足两个绑定但只被队列 Q2 接收一次");
        bingKeyMap.put("quick.brown.fox","不匹配任何绑定不会被任何队列接收到会被丢弃");
        bingKeyMap.put("quick.orange.male.rabbit","是四个单词不匹配任何绑定会被丢弃");
        bingKeyMap.put("lazy.orange.male.rabbit","是四个单词但匹配 Q2");

        bingKeyMap.forEach((k,v) -> {
            try {
                channel.basicPublish(EXCHANGE_NAME,k,null,v.getBytes(StandardCharsets.UTF_8));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });


    }

}
public class ReceiveLogsTopic01 {

    public static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] args) throws Exception {

        Channel channel = RabbitMQUtils.getChannel();

        //声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
        //声明一个队列
        String queueName = "Q1";
        channel.queueDeclare(queueName,false,false,false,null);
        channel.queueBind(queueName,EXCHANGE_NAME,"*.orange.*");
        System.out.println("等待接收消息");
        //接收消息
        DeliverCallback deliverCallback = (consumerTag, message) ->{
            System.out.println("ReceiveLogsTopic01:" + new String(message.getBody(), StandardCharsets.UTF_8));
            System.out.println("接收消息:" + queueName + "绑定键:" + message.getEnvelope().getRoutingKey());
        };

        channel.basicConsume(queueName,true,deliverCallback,consumerTag -> {});


    }

}

public class ReceiveLogsTopic02 {

    public static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] args) throws Exception {

        Channel channel = RabbitMQUtils.getChannel();

        //声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
        //声明一个队列
        String queueName = "Q2";
        channel.queueDeclare(queueName,false,false,false,null);
        channel.queueBind(queueName,EXCHANGE_NAME,"*.*.rabbit");
        channel.queueBind(queueName,EXCHANGE_NAME,"lazy.#");
        System.out.println("等待接收消息");
        //接收消息
        DeliverCallback deliverCallback = (consumerTag, message) ->{
            System.out.println("ReceiveLogsTopic01:" + new String(message.getBody(), StandardCharsets.UTF_8));
            System.out.println("接收消息:" + queueName + "绑定键:" + message.getEnvelope().getRoutingKey());
        };

        channel.basicConsume(queueName,true,deliverCallback,consumerTag -> {});


    }

}

在这里插入图片描述
测试结果:

规则结果
quick.orange.rabbit被队列 Q1Q2 接收到
lazy.orange.elephant被队列 Q1Q2 接收到
quick.orange.fox被队列 Q1 接收到
lazy.brown.fox被队列 Q2 接收到
lazy.pink.rabbit虽然满足两个绑定但只被队列 Q2 接收一次
quick.brown.fox不匹配任何绑定不会被任何队列接收到会被丢弃
quick.orange.male.rabbit是四个单词不匹配任何绑定会被丢弃
lazy.orange.male.rabbit是四个单词但匹配 Q2

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

真实感渲染的非正式调研与近期热门研究分享

真实感渲染的非正式调研与近期热门研究分享 1 期刊1 Top2 Venues 2 Rendering Reserach1 Material2 BRDF3 Appearance Modeling4 Capture5 Light Transport光线传播6 Differetiable Rendring-可微渲染7 Ray Tracing8 Denoising降噪9 NeRF 3 VR/AR4 Non-Photorealistic Renderin…

[GKCTF 2021]easycms 禅知cms

一道类似于渗透的题目 记录一下 首先扫描获取 登入界面 admin/12345登入 来到了后台 然后我们开始测试有无漏洞点 1.文件下载 设计 自定义 导出 然后进行抓包 解密后面的内容 发现是绝对路径了 所以这里我们要获取 flag 就/flag即可 L2ZsYWc /admin.php?mui&fdownlo…

从历史的探索到RFID固定资产管理的未来

在人类历史上&#xff0c;技术的进步一直是推动社会和工业发展的关键因素。其中&#xff0c;RFID技术的出现是一个重要的里程碑。让我们回顾一下RFID技术的历史&#xff0c;并探讨如何将其应用于固定资产管理&#xff0c;为企业提供更高效、智能的解决方案。 RFID&#xff08;R…

企业文件防泄密方法

企业文件防泄密方法 安企神数据防泄密系统下载使用 企业文件是企业的核心资产&#xff0c;其中可能包含大量的敏感信息&#xff0c;如客户资料、产品配方、财务数据等。一旦这些文件泄露&#xff0c;可能会给企业带来不可估量的损失。 然而&#xff0c;企业文件防泄密是确保…

第17期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练 Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

IDEA使用-通过Database面板访问数据库

文章目录 前言操作过程注意事项1.无法下载驱动2.“Database”面板不显示数据库表总结前言 作为一款强大IDE工具,IDEA具有很多功能,本文将以MariaDB数据库访问为例,详细介绍如何通过IDE工具的Database面板来访问数据库。 操作过程 不同的版本操作会略有差异,这里我们用于演…

Golang教程——配置环境,再探GoLand

文章目录 一、Go是什么&#xff1f;二、环境配置验证配置环境变量 三、安装开发者工具GoLand四、HelloGolang 一、Go是什么&#xff1f; Go&#xff08;也称为Golang&#xff09;是一种开源的编程语言&#xff0c;由Google开发并于2009年首次发布。Go语言旨在提供一种简单、高…

wireshark捕获DNS

DNS解析&#xff1a; 过滤项输入dns&#xff1a; dns查询报文 应答报文&#xff1a; 事务id相同&#xff0c;flag里 QR字段1&#xff0c;表示响应&#xff0c;answers rrs变成了2. 并且响应报文多了Answers 再具体一点&#xff0c;得到解析出的ip地址&#xff08;最底下的add…

SQL-正则表达式和约束

文章目录 主要内容一.正则表达式1.操作1代码如下&#xff08;示例&#xff09;: 2.操作2代码如下&#xff08;示例&#xff09;: 3.操作3代码如下&#xff08;示例&#xff09;: 4.操作4代码如下&#xff08;示例&#xff09;: 二.约束1.主键约束 2.自增长约束3.非空约束4.唯一…

2024年天津中德应用技术大学专升本物流管理专业课考试大纲

天津中德应用技术大学物流管理专业&#xff08;高职升本科&#xff09;2024年专业基础考试大纲 一、试卷类型 物流管理专业升本专业课考试共1套试卷&#xff0c;总分200分&#xff0c;考试时间为2小时。内容包含仓储与配送管理40%、物流基础30%&#xff0c;运输管理30%&#…

单目标应用:进化场优化算法(Evolutionary Field Optimization,EFO)求解微电网优化MATLAB

一、微网系统运行优化模型 微电网优化模型介绍&#xff1a; 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 二、进化场优化算法EFO 进化场优化算法&#xff08;Evolutionary Field Optimization&#xff0c;EFO&#xff09;由Baris Baykant Alagoz等人于2022年提出&…

接雨水 DP 双指针

力扣 接雨水 public class 接雨水 {public static int trap(int[] height){int res 0;int len height.length;int[] maxLeft new int[len];//存 i 左边最高的高度int[] maxRight new int[len];//存 i 右边最高的高度maxLeft[0] 0;maxRight[len - 1] 0; // DPfor (int i…

杀毒软件哪个好,杀毒软件有哪些

安全杀毒软件是一种专门用于检测、防止和清除计算机病毒、恶意软件和其他安全威胁的软件。这类软件通常具备以下功能&#xff1a; 1. 实时监测&#xff1a;通过实时监测计算机系统&#xff0c;能够发现并防止病毒、恶意软件等安全威胁的入侵。 2. 扫描和清除&#xff1a;可以…

使用 node.js 简单搭建Web服务 使用node简单搭建后端服务 使用node搭建服务

使用 node.js 简单搭建Web服务 使用node简单搭建后端服务 使用node搭建服务 1、初始化项目2、安装 Express.js Web 服务框架3、创建 app.js 主入口文件, 并且实现 GET、POST请求4、启动服务5、请求测试 1、初始化项目 例如项目名为 node-server-demo mkdir node-server-demo进…

办公软件有哪些,办公软件哪个好

办公软件是指为办公和生产工作而设计的软件&#xff0c;包括文字处理、表格处理、演示文稿、电子邮件、日历、计划等各种应用软件。办公软件可以提高工作效率&#xff0c;让人们更加便捷地完成各种工作任务。随着科技不断发展&#xff0c;办公软件也在不断更新和完善&#xff0…

安装OPENCMS过程记录

今天尝试安装个人网站&#xff0c;或者说是内容管理系统&#xff0c;wordpress 是PHP的&#xff0c;所以上网找了一个免费的&#xff0c;在知乎上基于Java的开源CMS有哪些推荐&#xff0c;各自特点是什么 - 知乎 (zhihu.com) 找了这个opencms&#xff0c;据说是免费&#xff0…

ARM 版 OpenEuler 22.03 部署 KubeSphere v3.4.0 不完全指南

作者&#xff1a;运维有术 前言 知识点 定级&#xff1a;入门级KubeKey 安装部署 ARM 版 KubeSphere 和 KubernetesARM 版 KubeSphere 和 Kubernetes 常见问题 实战服务器配置 (个人云上测试服务器) 主机名IPCPU内存系统盘数据盘用途ks-master-1172.16.33.1661650200KubeSp…

java后端返回数据给前端时去除值为空或NULL的属性、忽略某些属性

目录 一、使用场景 二、环境准备 1、引入依赖 2、实体类 三、示例 1、不返回空值 (1)方式 (2)测试 (3)说明 2、不返回部分属性 (1)方式 (2)测试 四、 Jackson常用注解 1、 JsonProperty 2、JsonPropertyOrder 3、JsonInclude 4、JsonIgnoreProperties 5、Jso…

第11章_数据处理之增删改

第11章_数据处理之增删改 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 1. 插入数据 1.1 实际问题 解决方式&#xff1a;使用 INSERT 语句向表中插入数据。 1.2 方式1&#xff1a;VALUES的方…

二叉树题目:路径总和 III

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;路径总和 III 出处&#xff1a;437. 路径总和 III 难度 5 级 题目描述 要求 给你二叉树的根结点 root \textt…