RabbitMQ学习笔记3-使用topic交换器
topic的路由规则里使用【.】号分隔单词,使用【*】号匹配1个单词,使用【#】匹配多个.和多个*。
在下面的例子中:
logger.*可以匹配logger.error和logger.warning,但logger*.error只能匹配logger.error
logger#可以匹配到logger.error和logger.warning。
下面的例子使用topic接收警告、错误的日志,并根据匹配的路由规则发送给不同的Queue队列来处理的例子:
日志生产者SenderWithTopicExchange
package com.yzl.test2; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; /**
* 使用topic交换器发送消息
* 分为警告和错误2种日志
* @author: yzl
* @date: 2016-10-22
*/
public class SenderWithTopicExchange {
//交换器名称
private static final String EXCHANGE_NAME = "myTopicExchange";
//路由键的前缀
private static final String BASE_ROUTING_KEY = "logger."; public static void main(String[] args) throws Exception {
//使用CountDownLatch控制2个线程一起运行
final CountDownLatch cdl = new CountDownLatch(2);
//连接到rabbitmq服务器
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
//创建一个信道
final Channel channel = connection.createChannel();
//定义一个名字为topicExchange的topic类型的exchange
channel.exchangeDeclare(EXCHANGE_NAME, "topic"); ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(new Runnable() {
@Override
public void run() {
try {
cdl.await();
//发送警告日志,绑定路由键:logger.warning
String warningMsg = "warning message is :";
for(int i=1; i<800; i++){
System.out.println("发送警告消息:" + warningMsg+i);
channel.basicPublish(EXCHANGE_NAME, BASE_ROUTING_KEY + "warning", null, (warningMsg+i).getBytes());
Thread.sleep(2000L);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
pool.submit(new Runnable() {
@Override
public void run() {
try {
cdl.await();
//发送错误日志,绑定路由键:logger.error
String errorMsg = "error message is :";
for(int i=1; i<1000; i++){
System.out.println("发送错误消息:" + errorMsg+i);
channel.basicPublish(EXCHANGE_NAME, BASE_ROUTING_KEY + "error", null, (errorMsg+i).getBytes());
Thread.sleep(2000L);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}); cdl.countDown();
cdl.countDown();
}
}
消息消费者ReceiverWithTopicExchange
package com.yzl.test2; import java.io.IOException; import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope; /**
* 使用topic交换器接收消息
*
* @author: yzl
* @date: 2016-10-22
*/
public class ReceiverWithTopicExchange {
// 交换器名称
private static final String EXCHANGE_NAME = "myTopicExchange"; public static void main(String[] args) throws Exception {
// 连接到rabbitmq服务器
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
// 创建一个信道
final Channel channel = connection.createChannel();
// 定义一个名字为topicExchange的topic类型的exchange
channel.exchangeDeclare(EXCHANGE_NAME, "topic"); //定义接收警告消息的队列
channel.queueDeclare("warningQueue", false, false, false, null);
//定义接收错误消息的队列
channel.queueDeclare("errorQueue", false, false, false, null);
//定义接收所有级别日志消息的队列
channel.queueDeclare("allLoggerQueue", false, false, false, null); //使用logger.warning路由键绑定myTopicExchange与warningQueue
channel.queueBind("warningQueue", EXCHANGE_NAME, "logger.warning");
//使用logger.error路由键绑定myTopicExchange与errorQueue
channel.queueBind("errorQueue", EXCHANGE_NAME, "logger.error");
//使用logger.*路由规则绑定myTopicExchange与allLoggerQueue
channel.queueBind("allLoggerQueue", EXCHANGE_NAME, "logger.*"); //只处理警告日志,使用手动ack确认
channel.basicConsume("warningQueue", false, new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body);
System.out.println("warningQueue accept a warning msg :" + msg);
channel.basicAck(envelope.getDeliveryTag(), false);
}
});
//只处理错误日志,使用手动ack确认
channel.basicConsume("errorQueue", false, new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body);
System.out.println("errorQueue accept a error msg :" + msg);
channel.basicAck(envelope.getDeliveryTag(), false);
}
});
//处理警告和错误日志,使用手动ack确认
channel.basicConsume("allLoggerQueue", false, new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body);
System.out.println("allLoggerQueue accept a logger msg :" + msg);
channel.basicAck(envelope.getDeliveryTag(), false);
}
});
}
}
结果输出:
发送警告消息:warning message is :1
发送错误消息:error message is :1
发送警告消息:warning message is :2
发送错误消息:error message is :2
发送错误消息:error message is :3
发送警告消息:warning message is :3
allLoggerQueue accept a logger msg :error message is :1
allLoggerQueue accept a logger msg :warning message is :1
errorQueue accept a error msg :error message is :1
warningQueue accept a warning msg :warning message is :1
warningQueue accept a warning msg :warning message is :2
errorQueue accept a error msg :error message is :2
allLoggerQueue accept a logger msg :warning message is :2
allLoggerQueue accept a logger msg :error message is :2
allLoggerQueue accept a logger msg :warning message is :3
errorQueue accept a error msg :error message is :3
warningQueue accept a warning msg :warning message is :3
allLoggerQueue accept a logger msg :error message is :3
消息处理流程:

RabbitMQ学习笔记3-使用topic交换器的更多相关文章
- RabbitMQ学习笔记4-使用fanout交换器
fanout交换器会把发送给它的所有消息发送给绑定在它上面的队列,起到广播一样的效果. 本里使用实际业务中常见的例子, 订单系统:创建订单,然后发送一个事件消息 积分系统:发送订单的积分奖励 短信平台 ...
- RabbitMQ学习笔记(五) Topic
更多的问题 Direct Exchange帮助我们解决了分类发布与订阅消息的问题,但是Direct Exchange的问题是,它所使用的routingKey是一个简单字符串,这决定了它只能按照一个条件 ...
- 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ
鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...
- RabbitMQ学习笔记1-hello world
安装过程略过,一搜一大把. rabbitmq管理控制台:http://localhost:15672/ 默认账户:guest/guest RabbitMQ默认监听端口:5672 JAVA API地 ...
- 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群
在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...
- (转) Rabbitmq学习笔记
详见原文: http://blog.csdn.net/shatty/article/details/9529463 Rabbitmq学习笔记
- RabbitMQ学习笔记五:RabbitMQ之优先级消息队列
RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...
- 官网英文版学习——RabbitMQ学习笔记(七)Topic
在上一篇中使用直接交换器改进了我们的系统,使得它能够有选择的进行接收消息,但它仍然有局限性——它不能基于多个条件进行路由.本节我们就进行能够基于多个条件进行路由的topics exchange学习. ...
- RabbitMQ学习笔记(六) RPC
什么RPC? 这一段是从度娘摘抄的. RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的 ...
随机推荐
- 文件和目录:access函数
access函数是按照实际用户ID和实际组ID进行访问权限测试的: #include <unistd.h> int access( const char *pathname, int mo ...
- [f]区间随机数函数
$.r = function(i, g) { var j = Math.random(), h = arguments.length; return h == 2 ? (i + Math.floor( ...
- Webpack使用教程三(webpack-dev-server)
Webpack给本地开发提供了一个可选的服务器webpack-dev-server.webpack-dev-server是一个很小的express应用,使用前需要用npm安装,它根据webpack.c ...
- SQLSERVER 2012之AlwaysOn -- 一次硬件升级引发的问题
这是上周遇到的一个案例:对已有的硬件进行升级而引发的问题,期间还触发了一个比较严重的BUG,可谓多灾多难:不过值得庆幸的是,在一连串连锁问题出现的时候,并没有出现人工操作失误(这往往是在处理故障中风险 ...
- Dynamic CRM 2013学习笔记(十)客户端几种查询数据方式比较
我们经常要在客户端进行数据查询,下面分别比较常用的几种查询方式:XMLHttpRequest, SDK.JQuery, SDK.Rest. XMLHttpRequest是最基本的调用方式,JQuery ...
- [MSSQL]SQL疑难杂症实战记录-巧妙利用PARTITION分组排名递增特性解决合并连续相同数据行
问题提出 先造一些测试数据以说明题目: DECLARE @TestData TABLE(ID INT,Col1 VARCHAR(20),Col2 VARCHAR(20)) INSERT INTO @T ...
- [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)
上一节链接:http://www.cnblogs.com/zjutlitao/p/4116783.html 前言: 在上一节中我们已经大致介绍了该软件的是什么.可以干什么以及界面的大致样子.此外还详细 ...
- [JAVA] java_实例 获得系统字体
这个代码可以帮助理解java是如何获取系统字体并设置文字字体: import java.awt.*; import java.awt.event.*; import javax.swing.JComb ...
- Marbles启动信息
body-parser deprecated undefined extended: provide extended option app.js:40:20 -------------------- ...
- hibernate懒加载(转载)
http://blog.csdn.net/sanjy523892105/article/details/7071139 懒加载详解 懒加载为Hibernate中比较常用的特性之一,下面我们详细来了解下 ...