Exchange中基于direct类型无法基于多种规则进行路由。

例如分析syslog日志,不仅需要基于severity(info/warning/critical/error)进行路由,还需要基于auth、cron或者kernal模式进行路由。

Topic exchange可以满足这种需求。

Topic exchange

基于topic类型交换器的routing key不是唯一的,而是一系列词,基于点区分。

例如:"stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit"

binding key也是类型方式。

*表示只匹配一个关键字

#可以匹配0或者多个关键字

Q1队列匹配对所有orange的关注

Q2队列可以监听rabbits,以及所有lazy开头的

quick.orange.fox只会进入Q1,lazy.brown.fox只会进入Q2

lazy.pink.rabbit尽管和两个topic都匹配上,但是只会进入队列以此

quick.brown.fox不会和任何队列进行绑定,因此会被丢弃

如果发送orange或者quick.orange.male.rabbit不会和任何队列进行绑定,也都会被丢弃。

Topic exchange功能很强大,类似其他exchange。当一个队列设置binding key为#,则它可以接收所有消息,不管routing key如何设置,类似fanout exchange。

当不设置*和#的话,topic exchange就类似direct exchange。

例子

发送消息

#!/usr/bin/env python
#-*- coding:utf8 -*-
import sys
import pika
import logging logging.basicConfig(format='%(levelname)s:$(message)s',level=logging.CRITICAL) def emit_log(): pika.connection.Parameters.DEFAULT_HOST = 'localhost'
pika.connection.Parameters.DEFAULT_PORT = 5672
pika.connection.Parameters.DEFAULT_VIRTUAL_HOST = '/'
pika.connection.Parameters.DEFAULT_USERNAME = 'guosong'
pika.connection.Parameters.DEFAULT_PASSWORD = 'guosong' para = pika.connection.Parameters() connection = pika.BlockingConnection(para) channel = connection.channel()
#声明一个topic_logs交换器,类型为topic
channel.exchange_declare(exchange='topic_logs',type='topic') #指定路由key
routing_key = sys.argv[1] if len(sys.argv) >1 else 'anonymous.info' message = ' '.join(sys.argv[2:]) or "info:Hello World!" #发送的时候指定routing_key为空,没有绑定队列到交换器上,消息将会丢失
#对于日志类消息,如果没有消费者监听的话,这些消息就会忽略
channel.basic_publish(exchange='topic_logs',routing_key=routing_key,body=message) #%r也是string类型
print "[x] Sent %r" % (message,) connection.close() if __name__ == '__main__':
emit_log()

接收消息

def callback(ch, method, properties, body):
print " [x] %r " % (body,) def receive_logs(): pika.connection.Parameters.DEFAULT_HOST = 'localhost'
pika.connection.Parameters.DEFAULT_PORT = 5672
pika.connection.Parameters.DEFAULT_VIRTUAL_HOST = '/'
pika.connection.Parameters.DEFAULT_USERNAME = 'guosong'
pika.connection.Parameters.DEFAULT_PASSWORD = 'guosong' para = pika.connection.Parameters() connection = pika.BlockingConnection(para) channel = connection.channel() #声明一个topic_logs交换器,类型为topic
channel.exchange_declare(exchange='topic_logs',type='topic') #声明一个随机队列,设置exclusive=True,在该consumer退出的时候,对应的队列被删除
result = channel.queue_declare(exclusive=True)
#获取随机队列的名称
queue_name = result.method.queue binding_keys = sys.argv[1:] if not binding_keys:
print >> sys.stderr, "Usage: %s [binding_key]" % sys.argv[0]
sys.exit(1) for binding_key in binding_keys:
#绑定交换器和队列
channel.queue_bind(exchange='topic_logs',queue=queue_name,routing_key=binding_key)
print '[*] Wating for logs.To exit press CTRL+C' #开始消费消息
channel.basic_consume(callback,queue=queue_name,no_ack=True) channel.start_consuming()

接收所有消息

python receive_logs_topic.py "#"

接收kern开头,包含一个关键字

python receive_logs_topic.py "kern.*"

多个绑定

python receive_logs_topic.py "kern.*" "*.critical"
guosong@guosong:~/code/rabbitmq/ch5$ python emit_log.py "kern.critical" "A critical kernel error"[x] Sent 'A critical kernel error'

guosong@guosong:~/code/rabbitmq/ch5$ ./receive_logs.py "kern.*"
[*] Wating for logs.To exit press CTRL+C
[x] 'A critical kernel error'

参考链接

http://www.rabbitmq.com/tutorials/tutorial-five-python.html

RabbitMQ之Topics(多规则路由)的更多相关文章

  1. RabbitMQ系列教程之四:路由(Routing)(转载)

    RabbitMQ系列教程之四:路由(Routing) (使用Net客户端) 在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息. 在本教程中,我们将为其添加一项功能 ...

  2. thinkphp 规则路由

    规则路由是一种比较容易理解的路由定义方式,采用ThinkPHP设计的规则表达式来定义. 规则表达式 规则表达式通常包含静态地址和动态地址,或者两种地址的结合,例如下面都属于有效的规则表达式: 'my' ...

  3. 【译】RabbitMQ:Topics

    在前面的教程中,我们对日志系统进行了功能强化.我们使用direct类型的交换器并且为之提供了可以选择接收日志的能力,替换了只能傻乎乎的广播消息的fanout类型的交换器.尽管使用direct类型的交换 ...

  4. 转载RabbitMQ入门(4)--路由

    路由 (使用Java客户端) 在先前的指南中,我们建立了一个简单的日志系统.我们可以将我们的日志信息广播到多个接收者. 在这部分的指南中,我们将要往其中添加一个功能-让仅仅订阅一个消息的子集成为可能. ...

  5. RabbitMQ系列教程之四:路由(Routing)

    (使用Net客户端)在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息.在本教程中,我们将为其添加一项功能 ,这个功能是我们将只订阅消息的一个子集成为可能. 例如, ...

  6. rabbitmq学习(五) —— 路由

    绑定(Bindings) 在上一个教程中,我们已经使用过绑定.你可能会记得如下代码: channel.queueBind(queueName, EXCHANGE_NAME, "") ...

  7. Go RabbitMQ(四)消息路由

    RabbitMQ_Routing 本节内容我们将对发布订阅增加一个特性:订阅子集.比如我们将一些危险的错误消息保存进硬盘中,同时在控制台仍然能够读取所有的消息 Bingings 上一节内容我们将队列跟 ...

  8. RabbitMQ Go客户端教程4——路由

    本文翻译自RabbitMQ官网的Go语言客户端系列教程,本文首发于我的个人博客:liwenzhou.com,教程共分为六篇,本文是第四篇--路由. 这些教程涵盖了使用RabbitMQ创建消息传递应用程 ...

  9. 译: 4. RabbitMQ Spring AMQP 之 Routing 路由

    在上一个教程中,我们构建了一个简单的fanout(扇出)交换.我们能够向许多接收者广播消息. 在本教程中,我们将为其添加一个功能 - 我们将只能订阅一部分消息.例如,我们将只能将消息指向感兴趣的特定颜 ...

随机推荐

  1. 简单的CSS颜色查看工具

    可以通过输入ARGB(A代表透明度)格式或者HEX格式查看颜色,也可以进行ARGB格式和者HEX格式转换,如下图 使用C#编写,我已将源代码压缩上传 下载地址:http://files.cnblogs ...

  2. [C#]Winform后台提交数据且获取远程接口返回的XML数据,转换成DataSet

    #region 接口返回的Xml转换成DataSet /// <summary> /// 返回的Xml转换成DataSet /// </summary> /// <par ...

  3. Extjs6(四)——侧边栏导航根据路由跳转页面

    本文基于ext-6.0.0 之前做的时候这个侧边栏导航是通过tab切换来切换页面的,但是总感觉不太对劲,现在终于发现怎么通过路由跳转了,分享给大家,可能有些不完善的地方,望大家读后可以给些指点.欢迎留 ...

  4. VMware Tools安装方法及共享文件夹设置方法

    正确安装好VMware Tools后,可以实现主机与虚拟机之间的文件共享, 可以设置共享文件夹,以及在主机与虚拟机之间直接进行复制黏贴的操作. 安装方法: 选择"虚拟机"-> ...

  5. 【深度学习系列】PaddlePaddle之手写数字识别

    上周在搜索关于深度学习分布式运行方式的资料时,无意间搜到了paddlepaddle,发现这个框架的分布式训练方案做的还挺不错的,想跟大家分享一下.不过呢,这块内容太复杂了,所以就简单的介绍一下padd ...

  6. C语言位操作

    #include <stdio.h> void print(int); int main(void) { int flag = 0xffe4; print(flag); printf(&q ...

  7. Android 6.0运行时权限

    一.Runtime Permissions Android 6.0在手机安全方面做的一个处理就是增加了运行时权限(Runtime Permissions). 新的权限机制更好的保护了用户的隐私,Goo ...

  8. SQL基本查询_单表查询(实验二)

    SQL基本查询_单表查询(实验二) 查询目标表结构及数据 emp empno ename job hiedate sal comn deptno 1007 马明 内勤 1992-6-12 4000 2 ...

  9. Web性能测试工具之ab入门篇

    1. ab简介 ab全称Apache Bench,是apache附带的一个小工具,它可以同时模拟多个并发请求,测试apache等Web服务器的最大负载压力. 本文通过一个简单的示例,介绍了使用ab进行 ...

  10. 暑假练习赛 007 C - OCR

    C - OCR Description standard input/outputStatements Optical Character Recognition (OCR) is one of th ...