RabbitMQ学习05

这篇具有很好参考价值的文章主要介绍了RabbitMQ学习05。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

交换机

1.Exchanges

1.1 概念

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

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 进行了绑定。RabbitMQ学习05,RabbitMQ,rabbitmq,学习

4. Fanout

4.1 介绍

    Fanout 这种类型非常简单。正如从名称中猜到的那样,它是将接收到的所有消息广播到它知道的所有队列中。系统中默认有些 exchange 类型
RabbitMQ学习05,RabbitMQ,rabbitmq,学习

RabbitMQ学习05,RabbitMQ,rabbitmq,学习
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 队列中去
RabbitMQ学习05,RabbitMQ,rabbitmq,学习
    在上面这张图中,我们可以看到 X 绑定了两个队列,绑定类型是 direct。队列 Q1 绑定键为 orange,队列 Q2 绑定键有两个:一个绑定键为 black,另一个绑定键为 green.
在这种绑定情况下,生产者发布消息到 exchange 上,绑定键为 orange 的消息会被发布到队列Q1。绑定键为 blackgreen 和的消息会被发布到队列 Q2,其他消息类型的消息将被丢弃。

5.2 多重绑定

RabbitMQ学习05,RabbitMQ,rabbitmq,学习
    当然如果 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 -> {});


    }

}

RabbitMQ学习05,RabbitMQ,rabbitmq,学习
测试结果:文章来源地址https://www.toymoban.com/news/detail-722016.html

规则 结果
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

到了这里,关于RabbitMQ学习05的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RabbitMQ学习笔记

    Broker:接受和分发消息的应用,例如RabbitMQ Server Virtual host:出于多租户和安全因素设计的,把AMQP的基本组件划分到一个虚拟的分组中,类似于网络中的namespace概念。当多个不同的用户使用同一个RabbitMQ server提供的服务时,可以划分出多个vhost,每个用户在自己的vhost创建exchang

    2024年01月17日
    浏览(19)
  • RabbitMQ 学习笔记

    学习视频:动力节点RabbitMQ教程|12小时学会rabbitmq消息中间件_哔哩哔哩_bilibili RabbitMQ 是使用 Erlang 语言开发的,所以要先下载安装 Erlang 下载时一定要注意版本兼容性: RabbitMQ Erlang 版本要求 — 兔子MQ 进入到安装目录的 sbin 目录下 进入到安装目录的 sbin 目录下 进入到安装目录

    2024年01月16日
    浏览(20)
  • RabbitMQ-基础学习

    参考:安装说明链接 1.Hello Word模式 写在测试类中: Providucer Consumer 2.Work Queues模式 生产者生产,两个消费者循环消费 P: C1: C2: 消费结果: 3.Publish/Subscribe订阅模式 消费着只需要绑定相应的队列,生产者需要创建交换机 4.Routing路由模式 路由模式相当于增加一层限制,只有

    2024年02月13日
    浏览(21)
  • RabbitMQ学习-延迟队列

    延迟队列 背:也就是给队列设置个过期时间,然后到时间消息变成死信,消费死信队列中的消息就行,再没什么玩意,演示队列优化就是不给队列这只TTL,再生产者代码中消息里面设置消息TTL, 因为 RabbitMQ 只会检查第一个消息是否过期 ,如果过期则丢到死信队列, 如果第

    2024年02月07日
    浏览(24)
  • RabbitMQ学习01

    生产者 产生数据发送消息的程序是生产者 交换机 交换机是 RabbitMQ 非常重要的一个部件,一方面它接收来自生产者的消息,另一方面它将消息推送到队列中。交换机必须确切知道如何处理它接收到的消息,是将这些消息推送到特定队列还是推送到多个队列,亦或者是把消息丢

    2024年02月08日
    浏览(19)
  • Rabbitmq学习

    1 同步调用适用于大多数场景 比如差一个订单状态 我们要求时效性 2 异步调用适用于高并发场景,依赖于异步管理器,能提高吞吐量,反应速度。 我使用的是centos8 直接安装rabbitmq会有很多问题 因为centos8 021年12月31日CentOS 8操作系统版本结束了生命周期(EOL),Linux社区已不

    2024年02月13日
    浏览(11)
  • RabbitMq深度学习

    什么是RabbitMq? RabbitMQ是一个开源的消息队列中间件,它实现了高级消息队列协议(AMQP)。它被广泛用于分布式系统中的消息传递和异步通信。RabbitMQ提供了一种可靠的、可扩展的机制来传递消息,使不同的应用程序能够相互之间进行通信。它支持多种编程语言和平台,并且具

    2024年02月10日
    浏览(19)
  • RabbitMQ入门学习笔记

    本文是笔者学习RabbitMQ的笔记,如果对你有所帮助,欢迎三连(点赞👍+收藏⭐+关注💖)   在现代的分布式系统中,消息传递变得愈发重要,而RabbitMQ作为一种高性能、可靠且灵活的消息队列解决方案备受青睐。作为开源软件,RabbitMQ提供了一个可靠的、可扩展的平台,用

    2024年02月15日
    浏览(24)
  • rabbitMQ的学习

    MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是message 而已,还是一种跨进程的通信机制,用于上下游传递消息。在互联网架构中,MQ 是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了 MQ 之后,消息发送上游

    2024年02月22日
    浏览(16)
  • RabbitMQ进阶学习

    在之前的练习作业中,我们改造了余额支付功能,在支付成功后利用RabbitMQ通知交易服务,更新业务订单状态为已支付。 但是大家思考一下,如果这里MQ通知失败,支付服务中支付流水显示支付成功,而交易服务中的订单状态却显示未支付,数据出现了不一致。 此时前端发送

    2024年03月13日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包