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. Linux基本符号

    Linux环境下一些常用的符号 ; 多个命令的分隔符 / 根目录或路径分隔符 > 重定向,数据沿箭头方向流动,原来文件内容会被丢弃 >> 追加重定向,在原来文件结尾追加内容 .. 上 ...

  2. IDEA Maven 三层架构 1、基本的Archetype 搭建

    JDK:1.8 Maven:3.3.9 三层架构:基于 SpringMVC 的 UI 层.业务逻辑层以及数据访问层 从对 Maven 的了解可以看出,三层架构的创建在于对文件夹的合理安排,他们通常是主 ...

  3. datagrid 列鼠标悬浮显示全部信息

    首次发表随笔,且是java新手,求不黑,可能在高手眼里好笑,嘿嘿1,样式设置超过字数限制显示省略号:<style type="text/css"> .datagrid- ...

  4. Nginx功能展示实验

    Nginx功能展示实验 Nging可以作为反代服务器:也可以作为负载均衡器,并自带根据对后端服务器健康状态检测具有增删服务器的功能:也可以作为纯Web服务器,提供Web服务. 本实验将使用Nginx实 ...

  5. (转)log4j使用介绍

    原文出自: log4j使用介绍 日志是应用软件中不可缺少的部分,Apache的开源项目Log4j是一个功能强大的日志组件,提供方便的日志记录.以下是个人经验,具体请参考Log4j文档指南. Log4j ...

  6. 使用vue-cli脚手架搭建简单项目框架

    1.首先已经安装了node,最好版本6以上. 2.安装淘宝镜像 大家都知道国内直接使用 npm 的官方镜像是非常慢的,这里推荐使用淘宝 NPM 镜像.这样就可以直接使用cnpm了. npm insta ...

  7. LeetCode 437. Path Sum III (路径之和之三)

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  8. hdu1285 确定比赛名次(拓扑排序)

    有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道 ...

  9. 2016 ACM/ICPC Asia Regional Dalian Online Football Games

    Football Games Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  10. 使用weinre远程调试

    1.调试环境: 1)使用nodejs搭建调试服务器: 先安装node,然后使用npm安装weinre,在node.js安装目录输入以下命令 npm install weinre 2)需要wifi环境和 ...