RabbitMQ之路由
为了实现一个新功能:只订阅消息的一个子集,例如只需要把严重的错误日志信息写入日志文件(存储到磁盘上),但同时仍然把所有的日志信息输出到控制台中。
绑定(Bindings)
创建绑定
channel.queue_bind(exchange=exchange_name,
queue=queue_name)
建立exchange和queue之间的关系,简单理解是这个队列对这个交换器的消息感兴趣。
绑定的时候可以带上一个额外的routing_key参数,为了避免与basic_publish参数混淆,叫做binding key.
创建一个带binding key的绑定
channel.queue_bind(exchange=exchange_name,
queue=queue_name,
routing_key='black')
binding key的含义取决于交换器的类型,对于fanout类型会忽略这个值。
Driect类型的交换器exchange
使用fanout类型的交换器exchange是广播类型,对于消息的过滤需要使用direct类型
使用direct类型的交换器,交换器将会对binding key和routing key进行精确匹配,从而确定消息该分发到哪个队列。

如上图,可以看到x交换器和两个队列进行绑定,第一个队列使用orange作为binding key,第二个队列有两个绑定,一个使用black,一个使用green。
这样,当routing key为orange的消息发布到交换器,会路由到队列Q1,black和green两个类型路由Q2,其他的所有消息将会被丢弃。
多个绑定(Multiple bindings)

多个队列使用相同的binding key是合法的。
可以添加一个x和Q1之间的绑定,也可以再添加一个x和Q2的绑定。这样以来,指定交换direct类型和fanout广播类型功能相同。
Emmiting logs
将会发送消息到一个direct exchange,把日志级别作为routing key。
这样负责处理接收的脚本可以选择要处理的日志级别。
创建一个direct类型的交换器
channel.exchange_declare(exchange='direct_logs',
type='direct')
然后发送一条消息:
channel.basic_publish(exchange='direct_logs',
routing_key=severity,
body=message)
severity值假定为info,warning,error中的一个
订阅(subscribing)
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue for severity in severities:
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key=severity)
为每一个日志级别创建一个新的绑定。
例子

将error信息发送到一个队列,将所有信息发送另一个队列
emit_log
#!/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()
#声明一个direct_logs交换器,类型为direct
channel.exchange_declare(exchange='direct_logs',type='direct') #指定日志级别
serverity = sys.argv[1] if len(sys.argv) >1 else 'info' message = '.'.join(sys.argv[1:]) or "info:Hello World!" #发送的时候指定routing_key为空,没有绑定队列到交换器上,消息将会丢失
#对于日志类消息,如果没有消费者监听的话,这些消息就会忽略
channel.basic_publish(exchange='logs',routing_key=serverity,body=message) #%r也是string类型
print "[x] Sent %r" % (message,) connection.close() if __name__ == '__main__':
emit_log()
接收者
#!/usr/bin/env python
#-*- coding:utf8 -*-
import sys
import pika
import logging logging.basicConfig(format='%(levelname)s:$(message)s',level=logging.CRITICAL) #回调函数,处理消息
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() #声明一个logs交换器,类型为fanout,不允许发布消息到不存在的交换器
channel.exchange_declare(exchange='direct_logs',type='direct') #声明一个随机队列,设置exclusive=True,在该consumer退出的时候,对应的队列被删除
result = channel.queue_declare(exclusive=True)
#获取随机队列的名称
queue_name = result.method.queue serverities = sys.argv[1:]
if not serverities:
print >> sys.stderr, "Usage: %s [info] [warning] [error]" % sys.argv[0]
sys.exit(1) for serverity in serverities:
#绑定交换器和队列
channel.queue_bind(exchange='logs',queue=queue_name,routing_key=serverity)
print '[*] Wating for logs.To exit press CTRL+C' #开始消费消息
channel.basic_consume(callback,queue=queue_name,no_ack=True)
channel.start_consuming() if __name__ == '__main__':
receive_logs()
如果只希望保存warning和error级别的日志到磁盘,只需要打开控制台并输入:
guosong@guosong:~/code/rabbitmq/ch4$ ./receive_logs.py warning error >logs
如果需要所有的话,执行如下命令:
guosong@guosong:~/code/rabbitmq/ch4$ ./receive_logs.py info warning error >logs
RabbitMQ之路由的更多相关文章
- RabbitMQ之路由(Routing)【译】
在上一节中,我们创建了一个简单的日志系统,可以广播消息到很多接收者. 这一节,我们将在上一节的基础上加一个功能--订阅部分消息.例如,我们只将严重错误信息写入到日志文件保存在磁盘上,同时我们能将所有的 ...
- 【译】RabbitMQ:路由(Routing)
在前一篇中,我们构建了一个简单的日志系统,我们已经能够广播消息到许多的接收者.在这一篇中,我们希望增加一个特性,让订阅消息的子集成为可能.例如,我们可以将重要的错误日志存放到日志文件(即,磁盘上面), ...
- RabbitMQ入门-路由-有选择的接受消息
比如一个日志系统,之前的处理方式呢,是各种类型(info,error,warning)的消息都发给订阅者,可是实际情况上不一定都需要.可能A需要error,其他的都不需要.那么就引入了今天的处理方式- ...
- RabbitMQ之路由键转发消息
RabbitMQ学习 参考:https://www.jianshu.com/p/6b62a0ed2491 消息队列:目前流行的有 Kafka.RabbitMQ.ActiveMQ等 功能:为了解决消息的 ...
- Rabbitmq(5) 路由模式
设置路由键 发送者 package com.aynu.bootamqp.service; import com.aynu.bootamqp.commons.utils.Amqp; import com ...
- RabbitMQ 的路由模式 Topic模式
模型 生产者 package cn.wh; import java.io.IOException; import java.util.concurrent.TimeoutException; impo ...
- 五.RabbitMQ之路由(Routing)和主题(topics)
翻译官网的文章已经翻译了几天了,这份官方文档写的总体算是很简洁易懂.它让我们很快的入门并了解了RabbitMQ的运作原理和使用方式.本篇最后介绍一下Exchange的另外两种类别,即direct和to ...
- rabbitmq (四) 路由
上文讲的是广播类型fanout 本章讲 direct和topic. 当使用广播类型fanout的时候: routingKey字段不起作用. direct:精确匹配 routingKey:匹配一个单词, ...
- .Net使用RabbitMQ详解
序言 这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其中,就把他抛开,我们只谈消息Rabbi ...
随机推荐
- [js插件开发教程]一步步开发一个可以定制配置的隔行变色小插件
隔行变色功能,不用js,直接用css伪类就可以做,这个实例可以作为js插件开发很好的入门级实例.本文实现的隔行变色包括以下功能: 1,支持2种常用结构共存( div元素 和 表格类型 ) 2,一个页面 ...
- 远程连接MySQL,防火墙阻止访问,解决方法
远程连接MySQL,防火墙阻止访问,解决方法 xp/2003添加防火墙例外端口 打开防火墙,选择例外选项卡,添加端口 名称:mysqlport 端口号:3306 选中TCP win7添加防火墙例外 ...
- Echarts数据可视化series-line线图,开发全解+完美注释
全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...
- Java多线程——创建线程的两种方式
创建线程方式一:继承Thread类. 步骤:1,定义一个类继承Thread类.2,覆盖Thread类中的run方法.3,直接创建Thread的子类对象创建线程.4,调用start方法开启线程并调用线程 ...
- vue-cli 自定义指令directive 添加验证滑块
vue项目注册登录页面遇到了一个需要滑块的功能,网上看了很多插件发现都不太好用,于是自己写了一个插件供大家参考: 用的是vue的自定义指令direcive,只需要在需要的组件里放入对应的标签嵌套即可: ...
- PE格式第九讲,资源表解析
PE格式第九讲,资源表解析 一丶熟悉Windows管理文件的方法 首先,为什么标题是这个,主要是为了下边讲解资源方便,因为资源结构体很乱.如果直接拿出来讲解,那么就会很晕. 1.windows管理文件 ...
- 解决Nginx+Tomcat时ContextPath不同的问题
1 问题描述 项目前端模板使用Thymeleaf,在对各种URL进行格式化输出时,都使用@{uri}代码.它会自动读取项目部署的虚拟路径,添加到URI的前端输出. 真实测试和生产环境中, ...
- 【前端】javascript实现导航栏筋斗云效果特效
实现效果: 实现效果如下图所示 实现原理: 什么是筋斗云效果: 这个效果很简单,就是鼠标移到其他导航目录时会有背景图片跟着鼠标滑动到当前的目录. 实现思路: 鼠标经过的时候,利用offsetLeft获 ...
- 基于容器微服务的PaaS云平台设计(二)通过kubernetes实现微服务容器管理
版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 ,博主地址:http://www.cnblogs.com/SuperXJ/ 上一章描述了基于spring cloud的微服务实例(实 ...
- 关于Python输出时间戳的问题
在我们的程序中,有时候想要知道程序的执行时间或者准确的停止时间,这时候就需要我们自己添加一个时间戳,以便我们做出判断和相应的处理. 下面是我亲测并收集的资料,菜鸟一枚,不全之处大神可给予补充和指正. ...