一、前言

  前面讲到direct类型的Exchange路由规则是完全匹配binding key与routing key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到binding key与routing key相匹配的Queue中,但这里的匹配规则有些不同,它约定: 

  • routing key为一个句点号“. ”分隔的字符串(我们将被句点号“. ”分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”
  • binding key与routing key一样也是句点号“. ”分隔的字符串
  • binding key中可以存在两种特殊字符“*”与“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)

  

  以上图中的配置为例,routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2,routingKey=”lazy.orange.fox”的消息会路由到Q1与Q2,routingKey=”lazy.brown.fox”的消息会路由到Q2,routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次,虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。

二、Exchange topic

  topic 和 direct 改动不多,就是routing key 和bind key 需要改一下

  生产端:

# -*- coding: UTF-8 -*-

import pika

# 创建一个连接
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost')) # 创建一个管道
channel = connection.channel() # 声明exchange 及类型
channel.exchange_declare(exchange='topic_log',
exchange_type='topic') # 输入信息,格式为 *.info from *.info test 类似
input_data = input('>>:').strip() # 将输入的信息以空格为分割,转换为列表
data_list = input_data.split(' ') # 三元运算,如果输入信息存在,就使用输入的信息data_list[0],否则用 'anonymous.info'
severity = data_list[0] if len(data_list) > 1 else 'anonymous.info' message = ' '.join(data_list[2:]) or 'hello,world!' # 这里的routing_key就是 data_list[0] 或 'info'
channel.basic_publish(exchange='topic_log',
routing_key=severity,
body=message)
print('[x] Sent %r:%r' % (severity, message)) connection.close()

  消费端:

  

# -*- coding: UTF-8 -*-

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost')) channel = connection.channel() # 声明exchange 及类型
channel.exchange_declare(exchange='topic_log',
exchange_type='topic') result = channel.queue_declare(exclusive=True) queue_name = result.method.queue # 在此我们定义一些列表,列表内容如下
# 这2个列表分别用来测试和routing_key匹配情况
# 第一种只允许接收info的信息
# 第二种允许接收error 和 mysql的信息 # severities = ['*.info']
severities = ['*.error', 'mysql.*'] for severity in severities:
channel.queue_bind(exchange='topic_log',
queue=queue_name,
routing_key=severity)
print(' [*] Waiting for logs. To exit press CTRL+C') def callback(ch, method, properties, body):
print(" [x] %r:%r" % (method.routing_key, body)) channel.basic_consume(callback,
queue=queue_name,
no_ack=True) channel.start_consuming()

  我们测试时,分别启动两个consumer。

  第一个consumer1 中使用   severities = ['*.info']

  第二个consumer2中使用   severities = ['*.error', 'mysql.*']

  生产者分别输入:   

appache.info from appache info test

nginx.error from nginx error test

mysql.info from mysql info test

  可以看到日志信息分别会汇总到两个consumer中, 其中 consumer1 会收到 appache.info 和 mysql.info的信息, 而 consumer2 会收到 nginx.error 和 mysql.info 的信息。

Rabbitmq--topic的更多相关文章

  1. rabbitmq+topic+java

    可参照github代码:https://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/EmitLogTopic.java 1. 新建m ...

  2. demo rabbitmq topic(主题模式),fanout(广播模式),轮询分发,确认接收Ack处理

    //durable = true 代表持久化 交换机和队列都要为true ,持久代表服务重启,没有处理的消息依然存在 //topic 根据不同的routkey 发送和接收信息 //fanout 广播模 ...

  3. 9.RabbitMQ Topic类型交换机

    RabbitMQ消息服务中Topic类型交换机根据通配符路由消息,*代表一个单词,#代表代表0或多个单词.   生产者 消费者   代码 Producer.java   package com.tes ...

  4. RabbitMQ Topic exchange

    Topic exchange topic与之前的每个类型都不同(ps:废话每个都是不同的).Topic解决了我们另一个需求.举个例子,有一个做资讯的公司,他们会收集各种科技公司的动态并且第一时间转发出 ...

  5. RabbitMQ topic 交换器

    topic交换器:"."将路由键分为几个标识符,"*"匹配一个, "#"可以匹配多个 1:路由键为*或者#的时候 *:只能匹配单个的字符串 ...

  6. Java使用RabbitMQ之订阅分发(Topic)

    使用RabbitMQ进行消息发布和订阅,生产者将消息发送给转发器(exchange),转发器根据路由键匹配已绑定的消息队列并转发消息,主题模式支持路由键的通配. 生产者代码: package org. ...

  7. RabbitMQ简单应用の主题模式(topic)

    Topic exchange(主题转发器) 发送给主题转发器的消息不能是任意设置的选择键,必须是用小数点隔开的一系列的标识符.这些标识符可以是随意,但是通常跟消息的某些特性相关联.一些合法的路由选择键 ...

  8. RabbitMQ入门_07_Fanout 与 Topic

    A. 用广播的方式实现发布订阅 参考资料:https://www.rabbitmq.com/tutorials/tutorial-three-java.html Fanout 类型的 Exchange ...

  9. spring boot整合RabbitMQ(Topic模式)

    1.Topic交换器介绍 Topic Exchange 转发消息主要是根据通配符. 在这种交换机下,队列和交换机的绑定会定义一种路由模式,那么,通配符就要在这种路由模式和路由键之间匹配后交换机才能转发 ...

  10. RabbitMQ指南之五:主题交换器(Topic Exchange)

    在上一章中,我们完善了我们的日志系统,用direct交换器替换了fanout交换器,使得我们可以有选择性地接收消息.尽管如此,仍然还有限制:不能基于多个标准进行路由.在我们的日志系统中,我们可能不仅希 ...

随机推荐

  1. scrapy-redis+selenium+webdriver解决动态代理ip和user-agent的问题(全网唯一完整代码解决方案)

    问题描述:在爬取一些反爬机制做的比较好的网站时,经常会遇见一个问题就网站代码是通过js写的,这种就无法直接使用一般的爬虫工具爬取,这种情况一般有两种解决方案 第一种:把js代码转为html代码,然后再 ...

  2. 阿里巴巴将在美国推出电子商务网站11 Main

    新浪科技讯 北京时间2月11日晚间消息,阿里巴巴集团周二向路透社证实,阿里巴巴将通过旗下子公司Vendio和Auctiva在美国推出一个电子商务网站. 该网站的名称为“11 Main”(11main. ...

  3. 大数据-storm学习资料视频

    storm学习资料视频 https://pan.baidu.com/s/18iQPoVFNHF1NCRBhXsMcWQ

  4. Python 函数内省

    函数内省(function introspection) 除了__doc__属性, 函数对象还有很多属性,对于下面的函数,可以使用dir()查看函数具有的属性: def factorial(n): r ...

  5. php分页类学习

    分页是目前在显示大量结果时所采用的最好的方式.有了下面这些代码的帮助,开发人员可以在多个页面中显示大量的数据.在互联网上,分​页是一般用于搜索结果或是浏览全部信息(比如:一个论坛主题).几乎在每一个W ...

  6. 7. I/O复用

    一.I/O复用的特点 能同时监听多个文件描述符 自身是阻塞的 当多个文件描述符同时就绪时,如果不采取额外的措施,程序就只能按顺序依次处理其中的每一个文件描述符 由于其第三个特点,所以服务器程序看起来仍 ...

  7. 王者荣耀交流协会第四次Scrum立会

    会议时间:2017年10月23号   18:00-18:28,时长28分钟. 会议地点:二食堂一楼第四个档口对着的靠路边的桌子. 立会内容: 1.小组成员汇报今日工作: 2.关于折线图与饼状图生成问题 ...

  8. 操作系统之实验二Step1-有序顺序表

    实验二Step1-有序顺序表 专业:商业软件工程     班级:商软2班     姓名:甘佳萍     学号:201406114207 实验要求:初始化 输入数组元素个数. 输入n个数,排序输出. 存 ...

  9. jdk&tomcat环境变量配置及同时运行多个tomcat方法

    一:jdk配置 安装jdk1.7.0_51,安装过程中所有选项保持默认:最后配置 JDK的环境变量: 在“我的电脑”上点右键—>“属性”—>“高级”—>“环境变量(N)”. 1.新建 ...

  10. c语言基础笔记

    一 :数据类型 1.float类型,在输出的时候可以使用 .数字  来把浮点数精确到小数点后几位,比如 printf("%.3f",float)精确到小数点后三位,不足补0 2.字 ...