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)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的 ...
随机推荐
- 字符串和json之间的互相转化
在Firefox,chrome,opera,safari,ie9,ie8等高级浏览器直接可以用JSON对象的stringify()和parse()方法. JSON.stringify(obj)将JSO ...
- 12 个 Web 设计师必备的 Bootstrap 工具
转自:http://www.oschina.net/translate/12-best-bootstrap-tools-for-web-designers Bootstrap是一个非常棒的前端网站开发 ...
- REST API 安全设计指南
0x01 REST API 简介 REST的全称是REpresentational State Transfer,表示表述性无状态传输,无需session,所以每次请求都得带上身份认证信息.rest是 ...
- codepage IMLangCodePages
http://baike.baidu.com/link?url=78DSTGAri8dvHNLQ03rThSKieJqhFwFWL4sQMao6cfaRSOUWN88QVBwmSJPCZch0vf ...
- windows下使用体验更好的控制台——ConsoleZ
转做前端开发以来,每天使用最频繁的工具就是控制台了,git提交代码要用,npm安装node包也要用,grunt task 也要用,可是系统自带的cmd太难用了, 那么问题就来了: "wind ...
- [ACM_图论] Fire Net (ZOJ 1002 带障碍棋盘布炮,互不攻击最大数量)
Suppose that we have a square city with straight streets. A map of a city is a square board with n ...
- ASP.NET MVC中三方登录: 微软、谷歌、Office365
创建一个MVC的工程,在Startup.Auth.cs文件中,我们能看到这样的一些代码: 这其实是微软已经帮我们实现好的三方登录的接口,我们只需要创建相应的开发者账号,并在其中配置好跟我们应用程序相关 ...
- java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
这个错误错了几次,必须做个标记 解决方法非常的简单: 最新的19版本会在你的项目下建立一个依赖包 Android Dependencies,在eclipse中右键这个文件夹,在Build Path选项 ...
- VR快速发展下,从业者如何把握机会?
美国科技博客VentureBeat周末刊登赛斯·沙赫纳(Seth Schachner)的文章,分析了在虚拟现实快速发展的情况下,业内所面临的机会,以及如何把握这些机会. 沙赫纳是资深的数字战略 ...
- paip.c3p0 nullpointexcept 配置文件根路径读取bug 解决
paip.c3p0 nullpointexcept 配置文件根路径读取bug 解决 windows ok linux犯错误... 查看loging, 初始化的时候儿jdbcurl,user,pwd都是 ...