RabbitMQ之Topics(多规则路由)
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(多规则路由)的更多相关文章
- RabbitMQ系列教程之四:路由(Routing)(转载)
RabbitMQ系列教程之四:路由(Routing) (使用Net客户端) 在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息. 在本教程中,我们将为其添加一项功能 ...
- thinkphp 规则路由
规则路由是一种比较容易理解的路由定义方式,采用ThinkPHP设计的规则表达式来定义. 规则表达式 规则表达式通常包含静态地址和动态地址,或者两种地址的结合,例如下面都属于有效的规则表达式: 'my' ...
- 【译】RabbitMQ:Topics
在前面的教程中,我们对日志系统进行了功能强化.我们使用direct类型的交换器并且为之提供了可以选择接收日志的能力,替换了只能傻乎乎的广播消息的fanout类型的交换器.尽管使用direct类型的交换 ...
- 转载RabbitMQ入门(4)--路由
路由 (使用Java客户端) 在先前的指南中,我们建立了一个简单的日志系统.我们可以将我们的日志信息广播到多个接收者. 在这部分的指南中,我们将要往其中添加一个功能-让仅仅订阅一个消息的子集成为可能. ...
- RabbitMQ系列教程之四:路由(Routing)
(使用Net客户端)在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息.在本教程中,我们将为其添加一项功能 ,这个功能是我们将只订阅消息的一个子集成为可能. 例如, ...
- rabbitmq学习(五) —— 路由
绑定(Bindings) 在上一个教程中,我们已经使用过绑定.你可能会记得如下代码: channel.queueBind(queueName, EXCHANGE_NAME, "") ...
- Go RabbitMQ(四)消息路由
RabbitMQ_Routing 本节内容我们将对发布订阅增加一个特性:订阅子集.比如我们将一些危险的错误消息保存进硬盘中,同时在控制台仍然能够读取所有的消息 Bingings 上一节内容我们将队列跟 ...
- RabbitMQ Go客户端教程4——路由
本文翻译自RabbitMQ官网的Go语言客户端系列教程,本文首发于我的个人博客:liwenzhou.com,教程共分为六篇,本文是第四篇--路由. 这些教程涵盖了使用RabbitMQ创建消息传递应用程 ...
- 译: 4. RabbitMQ Spring AMQP 之 Routing 路由
在上一个教程中,我们构建了一个简单的fanout(扇出)交换.我们能够向许多接收者广播消息. 在本教程中,我们将为其添加一个功能 - 我们将只能订阅一部分消息.例如,我们将只能将消息指向感兴趣的特定颜 ...
随机推荐
- 提纲挈领webrtc之vad检测
顾名思义,VAD(Voice Activity Detection)算法的作用是检测是否是人的语音,它的使用 范围极广,降噪,语音识别等领域都需要有vad检测.vad检测有很多方法,这里我们之介绍一 ...
- c#中字节数组byte[]、图片image、流stream,字符串string、内存流MemoryStream、文件file,之间的转换
字节数组byte[]与图片image之间的转化 字节数组转换成图片 public static Image byte2img(byte[] buffer) { MemoryStream ms = ne ...
- 关于限制DHCP服务器广播的另类方法
0. 引言 如图,家里有两台计算机,分别处于不同房间.其中一台PC1能够与光猫直连:另外一台PC2较远,考虑到光猫有WLAN功能,便使用了一个路由器无线桥接到光猫,然后有线连接到PC2(均与光猫处于同 ...
- 【转】各种图(流程图,思维导图,UML,拓扑图,ER图)简介
原文地址:各种图(流程图,思维导图,UML,拓扑图,ER图)简介 流程图 1.定义:流程图是对过程.算法.流程的一种图像表示,在技术设计.交流及商业简报等领域有广泛的应用. 2.案例 3.计算机语言只 ...
- MyBatis 原始Dao开发方式
原始Dao开发方法需要程序员编写Dao接口和Dao实现类. 映射文件 <?xml version="1.0" encoding="UTF-8" ?> ...
- Nodejs.热部署方法
在开发中我们修改了一点代码后要去重启服务器才能看到结果,为了省去这个过程我们以往经常使用热部署代码的方法 下面是使用"supervisor"来达到热部署能力的方法: sudo np ...
- svn 提交 working copy is not up-to-date
svn在提交时报错信息如下: working copy is not up-to-date svn:commit failed(details follow): svn:file "xxxx ...
- 基于vip和twemproxy代理实现redis集群的无感知弹性扩容
目标是实现redis集群的无感知弹性扩容 关键点 1是无感知,即对redis集群的用户来说服务ip和port保持不变 2.弹性扩容,指的是在需要时刻可以按照业务扩大redis存储容量. 最原始的twe ...
- 04-从零玩转JavaWeb-JVM内存详情分析
JVM内存划分栈与栈帧 JVM将内存主要划分为: 方法区 虚拟机栈 本地方法栈 堆 程序计数器 一.方法区:存放字节码,常量 ,静态变量,是一个共享的区域 二.虚拟机栈:执行方法其实就是栈帧入栈,出栈 ...
- Python多进程应用
在我之前的一篇博文中详细介绍了Python多线程的应用: 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼 但是由于GIL的存在,使得python多线程没有充分利用CPU的多核,为 ...