柯南君:看大数据时代下的IT架构(8)消息队列之RabbitMQ--案例(topic起航)
二、Topic(主题) (using the Java client)
上一篇文章中,我们进步改良了我们的日志系统。我们使用direct类型转发器,使得接收者有能力进行选择性的接收日志,,而非fanout那样,只能够无脑的转发。
为了在我们的系统中实现上述的需求,我们需要学习稍微复杂的主题类型的转发器(topic exchange)。
三、Topic exchange(主题转换)
- * 可以匹配一个标识符。
- # 可以匹配0个或多个标识符。
第一个标识符描述动物的速度,
第二个标识符描述动物的颜色,
第三个标识符描述动物的物种:<speed>.<color>.<species>。
我们创建3个绑定键:Q1与*.orange.*绑定Q2与*.*.rabbit和lazy.#绑定。:
另一方面,lazy.orange.male.rabbit,虽然是四个标识符,也可以与lazy.#匹配,从而转发至Q2。
注:主题类型的转发器非常强大,可以实现其他类型的转发器。
四、Putting it all together(全部代码)
- public class EmitLogTopic {
- private static final String EXCHANGE_NAME = "topic_logs";
- public static void main(String[] argv)
- throws Exception {
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("localhost");
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
- channel.exchangeDeclare(EXCHANGE_NAME, "topic");
- String routingKey = getRouting(argv);
- String message = getMessage(argv);
- channel.basicPublish(EXCHANGE_NAME, routingKey, null, message.getBytes());
- System.out.println(" [x] Sent '" + routingKey + "':'" + message + "'");
- connection.close();
- }
- //...
- }
接收端:ReceiveLogsTopic.java:
- public class ReceiveLogsTopic {
- private static final String EXCHANGE_NAME = "topic_logs";
- public static void main(String[] argv)
- throws Exception {
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("localhost");
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
- channel.exchangeDeclare(EXCHANGE_NAME, "topic");
- String queueName = channel.queueDeclare().getQueue();
- if (argv.length < 1){
- System.err.println("Usage: ReceiveLogsTopic [binding_key]...");
- System.exit(1);
- }
- for(String bindingKey : argv){
- channel.queueBind(queueName, EXCHANGE_NAME, bindingKey);
- }
- System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
- QueueingConsumer consumer = new QueueingConsumer(channel);
- channel.basicConsume(queueName, true, consumer);
- while (true) {
- QueueingConsumer.Delivery delivery = consumer.nextDelivery();
- String message = new String(delivery.getBody());
- String routingKey = delivery.getEnvelope().getRoutingKey();
- System.out.println(" [x] Received '" + routingKey + "':'" + message + "'");
- }
- }
- }
Run the following examples, including the classpath as in Tutorial 1 - on Windows, use %CP%.
To receive all the logs:
$ java -cp $CP ReceiveLogsTopic "#"
To receive all logs from the facility "kern":
$ java -cp $CP ReceiveLogsTopic "kern.*"
Or if you want to hear only about "critical" logs:
$ java -cp $CP ReceiveLogsTopic "*.critical"
You can create multiple bindings:
$ java -cp $CP ReceiveLogsTopic "kern.*" "*.critical"
And to emit a log with a routing key "kern.critical" type:
$ java -cp $CP EmitLogTopic "kern.critical" "A critical kernel error"
Have fun playing with these programs. Note that the code doesn't make any assumption about the routing or binding keys, you may want to play with more than two routing key parameters.
Some teasers:
- Will "*" binding catch a message sent with an empty routing key?
- Will "#.*" catch a message with a string ".." as a key? Will it catch a message with a single word key?
- How different is "a.*.#" from "a.#"?
五、注释版的程序实例(全部代码)
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- public class EmitLogTopic {
- private static final String EXCHANGE_NAME = "topic_logs";
- public static void main(String[] argv) throws Exception {
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("localhost");
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
- channel.exchangeDeclare(EXCHANGE_NAME, "topic");//声明topic类型的Exchange
- String routingKeyOne = "logs.error.one";// 定义一个路由名为“error”
- for (int i = 0; i <= 1; i++) {
- String messageOne = "this is one error logs:" + i;
- channel.basicPublish(EXCHANGE_NAME, routingKeyOne, null, messageOne
- .getBytes());
- System.out.println(" [x] Sent '" + routingKeyOne + "':'"
- + messageOne + "'");
- }
- System.out.println("################################");
- String routingKeyTwo = "logs.error.two";
- for (int i = 0; i <= 2; i++) {
- String messageTwo = "this is two error logs:" + i;
- channel.basicPublish(EXCHANGE_NAME, routingKeyTwo, null, messageTwo
- .getBytes());
- System.out.println(" [x] Sent '" + routingKeyTwo + "':'"
- + messageTwo + "'");
- }
- System.out.println("################################");
- String routingKeyThree = "logs.info.one";
- for (int i = 0; i <= 3; i++) {
- String messageThree = "this is one info logs:" + i;
- channel.basicPublish(EXCHANGE_NAME, routingKeyThree, null,
- messageThree.getBytes());
- System.out.println(" [x] Sent '" + routingKeyThree + "':'"
- + messageThree + "'");
- }
- channel.close();
- connection.close();
- }
- }
- [x] Sent 'logs.error.one':'this is one error logs:1'
- ################################
- [x] Sent 'logs.error.two':'this is two error logs:0'
- [x] Sent 'logs.error.two':'this is two error logs:1'
- [x] Sent 'logs.error.two':'this is two error logs:2'
- ################################
- [x] Sent 'logs.info.one':'this is one info logs:0'
- [x] Sent 'logs.info.one':'this is one info logs:1'
- [x] Sent 'logs.info.one':'this is one info logs:2'
- [x] Sent 'logs.info.one':'this is one info logs:3'
第一个C端的代码如下:
- package com.abin.rabbitmq;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
public class ReceiveLogsTopic {
private static final String EXCHANGE_NAME = "topic_logs";// 定义Exchange名称
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "topic");// 声明topic类型的Exchange
String queueName = "queue_topic_logs1";// 定义队列名为“queue_topic_logs1”的Queue
channel.queueDeclare(queueName, false, false, false, null);
// String routingKeyOne = "*.error.two";// "error"路由规则
// channel.queueBind(queueName, EXCHANGE_NAME, routingKeyOne);// 把Queue、Exchange及路由绑定
String routingKeyTwo = "logs.*.one";//通配所有logs下第三词(最后一个)词为one的消息
channel.queueBind(queueName, EXCHANGE_NAME, routingKeyTwo);
System.out.println(" [*] Waiting for messages.");
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
String routingKey = delivery.getEnvelope().getRoutingKey();
System.out.println(" [x] Received '" + routingKey + "':'" + message
+ "'");
}
}
} - 第二个C端的运行结果如下:
- [*] Waiting for messages.
[x] Received 'logs.error.one':'this is one error logs:0'
[x] Received 'logs.error.one':'this is one error logs:1'
[x] Received 'logs.error.two':'this is two error logs:0'
[x] Received 'logs.error.two':'this is two error logs:1'
[x] Received 'logs.error.two':'this is two error logs:2'
[x] Received 'logs.info.one':'this is one info logs:0'
[x] Received 'logs.info.one':'this is one info logs:1'
[x] Received 'logs.info.one':'this is one info logs:2'
[x] Received 'logs.info.one':'this is one info logs:3'
柯南君:看大数据时代下的IT架构(8)消息队列之RabbitMQ--案例(topic起航)的更多相关文章
- 柯南君:看大数据时代下的IT架构(5)消息队列之RabbitMQ--案例(Work Queues起航)
二.Work Queues(using the Java Client) 走起 在第上一个教程中我们写程序从一个命名队列发送和接收消息.在这一次我们将创建一个工作队列,将用于分发耗时的任务在多个工 ...
- 柯南君:看大数据时代下的IT架构(4)消息队列之RabbitMQ--案例(Helloword起航)
柯南君:看大数据时代下的IT架构(4)消息队列之RabbitMQ--案例(Helloword起航) 二.起航 本章节,柯南君将从几个层面,用官网例子讲解一下RabbitMQ的实操经典程序案例,让大家重 ...
- 柯南君:看大数据时代下的IT架构(3)消息队列之RabbitMQ-安装、配置与监控
柯南君:看大数据时代下的IT架构(3)消息队列之RabbitMQ-安装.配置与监控 一.安装 1.安装Erlang 1)系统编译环境(这里采用linux/unix 环境) ① 安装环境 虚拟机:VMw ...
- 看大数据时代下的IT架构(1)业界消息队列对比
一.MQ(Message Queue) 即 消息队列,一般用于应用系统解耦.消息异步分发,能够提高系统吞吐量.MQ的产品有很多,有开源的,也有闭源,比如ZeroMQ.RabbitMQ. ActiveM ...
- 柯南君:看大数据时代下的IT架构(2)消息队列之RabbitMQ-基础概念详细介绍
一.基础概念详细介绍 1.引言 你是否遇到过两个(多个)系统间需要通过定时任务来同步某些数据?你是否在为异构系统的不同进程间相互调用.通讯的问题而苦恼.挣扎?如果是,那么恭喜你,消息服务让你可以很轻松 ...
- 柯南君:看大数据时代下的IT架构(6)消息队列之RabbitMQ--案例(Publish/Subscribe起航)
二.Publish/Subscribe(发布/订阅)(using the Java Client) 为了说明这个模式,我们将构建一个简单的日志系统.它将包括两个项目: 第一个将发出日志消息 第二个将接 ...
- 柯南君:看大数据时代下的IT架构(9)消息队列之RabbitMQ--案例(RPC起航)
二.Remote procedure call (RPC)(using the Java client) 三.Client interface(客户端接口) 为了展示一个RPC服务是如何使用的,我们将 ...
- 柯南君:看大数据时代下的IT架构(7)消息队列之RabbitMQ--案例(routing 起航)
二.Routing(路由) (using the Java client) 在前面的学习中,构建了一个简单的日志记录系统,能够广播所有的日志给多个接收者,在该部分学习中,将添加一个新的特点,就是可以只 ...
- 大数据时代下EDM邮件营销的变革
根据研究,今年的EDM邮件营销的邮件发送量比去年增长了63%,许多方法可以为你收集用户数据,这些数据可以帮助企业改善自己在营销中的精准度,相关性和执行力. 最近的一项研究表明,中国800强企业当中超过 ...
随机推荐
- Android Activity之 setContentView()总结
从一开始hello world的第一个安卓应用开始,Activity 自动生成,布局自动生成,直接修改布局,在Activity中,findviewById()找到view,然后处理相应的业务逻辑即可, ...
- Apache-Tomcat 和 Apache-Maven配置
1.1.下载安装文件 官网对应版本下载,例:apache-tomcat-8.0.35-windows-x64.zip 1.2.指定对应的安装目录: 例:D:\JavaSoft\apache-tomca ...
- iOS 倒计时
// // RootViewController.m // MyTimerDemo // // Created by huluo on 1/21/14. // Copyright (c) 2014 b ...
- ubuntu 14.04 vnc use gnome(ubuntu14.04 gnome for vnc4server)
New 'jenkinsmaster.cc:3 (root)' desktop is jenkinsmaster.cc:3 Starting applications specified in /ro ...
- OC中ARC forbids explicit message send of release错误(转)
ARC forbids explicit message send of'release' 很显然,是ARC的问题. 错误原因:在创建工程的时候点选了“Use Automatic Reference ...
- 不同版本的 IIS 中使用 ASP.NET MVC(C#)【转】
由微软 ASP.NET 团队|2008 年 8 月 19 日 推特 在本教程中,您将学习在不同版本的 Internet Information Services 中如何使用 ASP.NET MVC 和 ...
- Linux mint 17中文输入法安装,改动linux mint与windows7双系统启动顺序
安装好linux mint17后,进入mint系统,首先须要一个比較合适的中文输入法. 一.首先迎来的就是安装中文输入法了,之前听说搜狗为ubuntu kinly定制了输入法,所以就想安装搜狗输入法, ...
- java中文乱码解决之道(三)—–编码详情:伟大的创想—Unicode编码
原文出处:http://cmsblogs.com/?p=1458 随着计算机的发展.普及,世界各国为了适应本国的语言和字符都会自己设计一套自己的编码风格,正是由于这种乱,导致存在很多种编码方式,以至于 ...
- AngularJs(八) 过滤器filter创建
大纲 示例 过滤器的使用 创建过滤器 demo 这是整个示例demo 1.filter.js文件 angular.module("exampleApp", []) .constan ...
- CAD创建不规则形状视口
选择CAD模型空间中多段线,在指定的布局中创建视口,方法如下: /// <summary> /// 创建视口 /// </summary> /// <param name ...