RabbitMQ 原文译05--Topics
2016-06-13 17:20
274 查看
在之前的系统中,我们改进了我们的日志系统,我们使用direct 交换机代替fanout交换机,可以实现选择性的接受日志。
虽然使用direct 交换机改进了我们的系统,但是对于多种条件的判断,依然存在问题。如我们不仅仅想要根据日志的级别来订阅日志,同时也希望可以通过发出日志的源(即日志的生产者)来订阅。你也许已经通过unix 的工具syslog知道了这个概念,它同时通过级别(info/warn/crit...)和源(auth/cron/kern...).这种方式给了我们很大的灵活性--我们可以同时监听来自cron的critical 级别的错误消息和来自kern的所有消息。
为了在我们的系统中实现这种功能,我们需要学习更为复杂的交换机类型 --topic
绑定的key必须也是同样个格式,topic交换机背后的原理类似于把带有特定key的消息发送到所有跟这个key相匹配的队列上去,然而对于bindingKey这里有两个特殊的情况:
1:"*"可以代表一个单词(是单词不是字符--即"."分割的单词)
2:"?"可以代表0个或多个单词
例如:
View Code
运行下面的案例:
接收所有的日志:
接收所有的"kern"源的日志:
或者仅仅接受"critical"的日志:
你可以创建多个绑定:
发送一个routingkey是 "kern.critical"的消息
虽然使用direct 交换机改进了我们的系统,但是对于多种条件的判断,依然存在问题。如我们不仅仅想要根据日志的级别来订阅日志,同时也希望可以通过发出日志的源(即日志的生产者)来订阅。你也许已经通过unix 的工具syslog知道了这个概念,它同时通过级别(info/warn/crit...)和源(auth/cron/kern...).这种方式给了我们很大的灵活性--我们可以同时监听来自cron的critical 级别的错误消息和来自kern的所有消息。
为了在我们的系统中实现这种功能,我们需要学习更为复杂的交换机类型 --topic
Topic 交换机
发送到topic的交换机不能是任意routing_key,而必须是一系列使用"."。这些单词可以是任意的单子,单通常情况是是跟当前消息有关的一些功能,例如:"stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit".你可以指定任意多个字符,单上线是255字节。绑定的key必须也是同样个格式,topic交换机背后的原理类似于把带有特定key的消息发送到所有跟这个key相匹配的队列上去,然而对于bindingKey这里有两个特殊的情况:
1:"*"可以代表一个单词(是单词不是字符--即"."分割的单词)
2:"?"可以代表0个或多个单词
例如:
using System; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; class ReceiveLogsTopic { public static void Main(string[] args) { var factory = new ConnectionFactory() { HostName = "localhost" }; using(var connection = factory.CreateConnection()) using(var channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: "topic_logs", type: "topic"); var queueName = channel.QueueDeclare().QueueName; if(args.Length < 1) { Console.Error.WriteLine("Usage: {0} [binding_key...]", Environment.GetCommandLineArgs()[0]); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); Environment.ExitCode = 1; return; } foreach(var bindingKey in args) { channel.QueueBind(queue: queueName, exchange: "topic_logs", routingKey: bindingKey); } Console.WriteLine(" [*] Waiting for messages. To exit press CTRL+C"); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); var routingKey = ea.RoutingKey; Console.WriteLine(" [x] Received '{0}':'{1}'", routingKey, message); }; channel.BasicConsume(queue: queueName, noAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } }
View Code
运行下面的案例:
接收所有的日志:
ReceiveLogsTopic.exe "#"
接收所有的"kern"源的日志:
ReceiveLogsTopic.exe "kern.*"
或者仅仅接受"critical"的日志:
ReceiveLogsTopic.exe "*.critical"
你可以创建多个绑定:
ReceiveLogsTopic.exe "kern.*" "*.critical"
发送一个routingkey是 "kern.critical"的消息
EmitLogTopic.exe "kern.critical" "A critical kernel error"
相关文章推荐
- rk3188--12.linux内核中工作队列的实现
- 『九个月实现破亿用户的可扩展架构』学习笔记
- Linux日志文件总管――logrotate
- c#使用WebClient登录网站抓取登录后的网页
- nginx限制某个IP同一时间段的访问次数
- 几个设计相关的网站
- 字符设备驱动相关内容
- 坑系列 --- 高可用架构的银弹
- ognl.OgnlException: source is null for getProperty(null, "0")
- rk3188--5.android input 系统架构分析
- Openfire for mac 环境搭建
- 网站构建 初级教程
- iTunes Connect Developer
- linux 变量设置
- nginx+fastcgi+c++/php搭建web服务
- linux cntlm代理的配置
- 一些优秀的学习网站(Android)
- CentOS 6.5下Samba服务器的安装与配置
- 2016.6.13 零基础学习hadoop到上手工作线路指导(中级篇)
- nginx笔记之fastcgi_param解释