惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
MyScale Blog
MyScale Blog
Recent Announcements
Recent Announcements
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
V
V2EX
MongoDB | Blog
MongoDB | Blog
Microsoft Security Blog
Microsoft Security Blog
博客园 - 三生石上(FineUI控件)
Stack Overflow Blog
Stack Overflow Blog
U
Unit 42
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
H
Help Net Security
D
DataBreaches.Net
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
T
The Blog of Author Tim Ferriss
C
Check Point Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

牛牛技术客栈

设计模式-备忘录模式 - OXOXTECH 牛牛技术客栈 设计模式-中介者模式 - OXOXTECH 牛牛技术客栈 Linux【Ubuntu】修改ssh默认端口 - OXOXTECH 牛牛技术客栈 设计模式-迭代器模式 - OXOXTECH 牛牛技术客栈 scheduled定时任务的三种基本实现方式 - OXOXTECH 牛牛技术客栈 Apriori - 基于关联规则的推荐算法(三) - OXOXTECH 牛牛技术客栈 Apriori - 基于关联规则的推荐算法(二) - OXOXTECH 牛牛技术客栈 Apriori - 基于关联规则的推荐算法(一) - OXOXTECH 牛牛技术客栈 基于JavaFX的桌面端网络调试工具 - OXOXTECH 牛牛技术客栈 Golang Channel的原理介绍 - OXOXTECH 牛牛技术客栈 Go语言Map的原理分析 - OXOXTECH 牛牛技术客栈 Go语言错误处理(panic)的最佳实践 - OXOXTECH 牛牛技术客栈 设计模式-解释器模式 - OXOXTECH 牛牛技术客栈 Redis报错Redis is configured to save RDB snapshots, but it's currently unable to persist to disk. go-webpbin库在Linux报错failed to encode image to WebP: exit status 1.......的问题 exe4j 打包加密的jar - OXOXTECH 牛牛技术客栈 Go生成图形验证码示例 - OXOXTECH 牛牛技术客栈 澳门一天游:一日尽享东方与西方的交融之美 - OXOXTECH 牛牛技术客栈 设计模式-命令模式 - OXOXTECH 牛牛技术客栈 别再自己瞎写工具类了,SpringBoot内置工具类应有尽有 - OXOXTECH 牛牛技术客栈 中山一日游 - OXOXTECH 牛牛技术客栈 设计模式-责任链模式 - OXOXTECH 牛牛技术客栈 起舞吧,齐舞吧 - OXOXTECH 牛牛技术客栈 设计模式-组合模式 - OXOXTECH 牛牛技术客栈 Go语言Web开发|GoFrame框架入门笔记 - OXOXTECH 牛牛技术客栈 Java打包exe教程 - OXOXTECH 牛牛技术客栈 设计模式-代理模式 - OXOXTECH 牛牛技术客栈 MySQL存储过程的优缺点有哪些? - OXOXTECH 牛牛技术客栈 前端渲染优化有哪些? - OXOXTECH 牛牛技术客栈 HTTP状态码及其含义 - OXOXTECH 牛牛技术客栈
RabbitMQ系列(五)Topic模型 - OXOXTECH 牛牛技术客栈
Jensen · 2023-03-03 · via 牛牛技术客栈

Jensen 后端 教程, 技术, MQ

Topic 模型

上一篇文章《RabbitMQ系列(四)通信模型之路由模型》中,简单的介绍了一下RabbitMQ的路由模型。这篇文章来学习一下RabbitMQ中的topic模型,Topic 模型是 RabbitMQ 的高级模型之一,Topic 模型使用了通配符的概念,可以匹配更灵活的路由规则。topic模式相当于是对路由模式的一个升级,topic模式主要就是在匹配的规则上可以实现模糊匹配。

在 Topic 模型中,生产者将消息发送到交换机,交换机根据消息的 routing key 将消息转发到对应的队列中。与 Direct 模型不同的是,Topic 模型中 routing key 支持通配符匹配,其中 '*' 可以匹配一个单词,'#' 可以匹配多个单词。例如,"order.*" 可以匹配 "order.create","order.delete" 等消息,而 "order.#" 可以匹配 "order.create.one","order.delete.two" 等消息。

适用场景

Topic 模型适用于需要灵活的消息路由规则的场景,例如:

  1. 新闻网站订阅分类消息;
  2. 电商网站订阅商品分类消息;
  3. 金融机构订阅股票市场消息等。

演示

1. 生产者


// 生产者
public class Producer {
    private static final String EXCHANGE_NAME = "exchange_topic_1";
    private static final String EXCHANGE_ROUTING_KEY1 = "topic.km";
    private static final String EXCHANGE_ROUTING_KEY2 = "topic.km.001";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        for (int i = 0; i < 100; i++) {
            // topic在路由模型的基础上,只有路由的key发生改变,其余的都不变
            if (i % 2 == 0) {
                channel.basicPublish(EXCHANGE_NAME, EXCHANGE_ROUTING_KEY1, MessageProperties.PERSISTENT_TEXT_PLAIN, ("topic模型发送的第 " + i + " 条信息").getBytes());
            } else {
                channel.basicPublish(EXCHANGE_NAME, EXCHANGE_ROUTING_KEY2, MessageProperties.PERSISTENT_TEXT_PLAIN, ("topic模型发送的第 " + i + " 条信息").getBytes());
            }
        }
        channel.close();
        connection.close();
    }
}

2. 消费者

// 消费者1
public class Consumer1 {
    private static final String QUEUE_NAME = "queue_topic_1";
    private static final String EXCHANGE_NAME = "exchange_topic_1";
    private static final String EXCHANGE_ROUTING_KEY = "topic.*";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, EXCHANGE_ROUTING_KEY);
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1接收到的消息是:" + new String(body));
            }
        };
        channel.basicConsume(QUEUE_NAME, true, defaultConsumer);
    }
}

// 消费者2
public class Consumer2 {
    private static final String QUEUE_NAME = "queue_topic_2";
    private static final String EXCHANGE_NAME = "exchange_topic_1";
    private static final String EXCHANGE_ROUTING_KEY = "topic.#";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, EXCHANGE_ROUTING_KEY);
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者2接收到的消息是:" + new String(body));
            }
        };
        channel.basicConsume(QUEUE_NAME, true, defaultConsumer);
    }
}

3. 测试

先启动2个消费者,再启动生产者

消费者1订阅的是 "order.*" 的消息,消费者2订阅的是 "order.#" 的消息,可以得到以下结果:

消费者1接收到的消息是:"Topic 模型发送的偶数条消息"

消费者2接收到的消息是:"Topic 模型发送的全部消息"

小结

本文介绍了 RabbitMQ 通信模型中的 Topic 模型的使用,通过交换机和 routing key 实现更灵活的消息路由。在实际使用过程中,需要注意以下几点:

  1. 路由键的格式应该是多个单词组成,用 '.' 分隔;
  2. '#' 匹配多个单词,'*' 匹配一个单词;
  3. 一个队列可以绑定多个 routing key;
  4. 如果交换机没有匹配到任何一个队列,则会抛弃该消息。

原文地址:  https://mp.weixin.qq.com/s/VFSys052MlEUbJq4AkSYuw

说点什么吧...

共 0 条评论