一、前言

  前面讲到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. 机器学习之决策树(ID3)算法

    最近刚把<机器学习实战>中的决策树过了一遍,接下来通过书中的实例,来温习决策树构造算法中的ID3算法. 海洋生物数据:   不浮出水面是否可以生存 是否有脚蹼 属于鱼类 1 是 是 是 2 ...

  2. 数据时代的的企业管理 记SAP商业同略会

    [PConline 资讯]在2012 SAP中国商业同略会城市论坛深圳站上,自SAP中国的萧洁云总裁和张志琦先生,对SAP中国的战略.SAP的技术战略,以及SAP对于行业趋势分析与媒体进行了沟通,对数 ...

  3. Live Archive 训练题

    7091 Height Ordering Mrs. Chambers always has her class line up in height order (shortest at the fro ...

  4. CF 1008B Turn the Rectangles(水题+贪心)

    There are n rectangles in a row. You can either turn each rectangle by 90 degrees or leave it as it ...

  5. c# WPS DLL及其调用

    1.dll分享(含xsl及docx的dll) 链接:https://pan.baidu.com/s/1c1ImV14OndmvIb4W-_WL2A 密码:d2rx 2.方法: 1.先在类的前面(类外面 ...

  6. 严重: Failed to destroy end point associated with ProtocolHandler ["http-nio-8080"] java.lang.NullPointer

    刚接触servlet类,按照课本的方法使用eclipse新建了一个servlet类. 新建完成后,在web.xml里面进行注册 这时候就会报错了. 五月 07, 2016 11:23:28 上午 or ...

  7. Spring1()

    目的: 降低Java开发的复杂性 使用策略: 基于POJO的轻量级和最小侵入式的编程 通过依赖注入和面向接口实现松耦合 基于切面和惯例进行声明式编程 通过切面和模版减少样式代码 依赖注入:由Sprin ...

  8. 使用fprof基本步骤

    $erl -name a@localhost -setcookie abc -remsh b@localhost >fprof:trace([start, {file, "/home/ ...

  9. [2017BUAA软工]第二次博客作业:代码复审

    〇.comment链接 https://github.com/hanayashiki/Sudoku/issues/1 一.代码复审 1.概要部分 (1)代码能符合需求和规格说明么? 经测试,对于合法输 ...

  10. mysql 8 server windows 安装经验分享

    windows下安装一般分为文件/msi安装文件 本章我们说的是文件行的mysql server 安装 下载地址:https://dev.mysql.com/downloads/mysql/ 下载完后 ...