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)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的 ...
随机推荐
- C# async await 学习笔记1
由于我的开发工具为vs.net 2010(.net 4.0),需先做以下两步才能进行: 1.下载并安装Async CTP (http://www.microsoft.com/en-us/downloa ...
- 『TCP/IP详解——卷一:协议』读书笔记——04
2013-08-18 16:31:17 第2章 链路层 2.1 引言 链路层主要有三个目的: 为IP模块发送和接受IP数据报 为ARP模块发送ARP请求和接受ARP应答 为RARP发送RARP请求和接 ...
- [转]node.js学习笔记(二)
二.express 1.安装 express4 npm --registry=http://registry.npmjs.org install -g express-generator (全局) 2 ...
- ManyToMany【项目随笔】关于异常object references an unsaved transient instance
在保存ManyToMany 时出现异常: org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.Tran ...
- 记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?)
记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的, ...
- 微软BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server)
[公告]本博客于2015年10月起不再更新 新博客文章主要发表在商业智能BI社区: http://www.flybi.net/blog/biwork 博客地图自动分类 文章目录方便更好的导航,阅读文章 ...
- 用jstl截取字符串
用jstl截取字符串 2011-08-01 08:55 5485人阅读 评论(0) 收藏 举报 stringfunctionjavahtmljspencoding jstl以前在jsp页面截取字符串时 ...
- jenkins2 pipeline介绍
文章来自:http://www.ciandcd.com 文中的代码来自可以从github下载: https://github.com/ciandcd 什么是jenkins2的pipeline? ...
- 解析json实例
解析项目目录中的一个json文件,将之转化为List的一个方法. package com.miracles.p3.os.util; import com.miracles.p3.os.mode.Vid ...
- 往linux上传、下载
http://skypegnu1.blog.51cto.com/8991766/1538371