官网英文版学习——RabbitMQ学习笔记(六)Routing
有选择的接收消息。
上一节我们使用的是fanout exchange来实现消息的发布/订阅模式,这并没有给我们带来多大的灵活性——它只能够让人盲目地进行广播。而本节我们采用direct类型的交换器来实现有选择的接收消息。直接交换器背后的路由算法很简单——消息传递到绑定键与消息的路由键完全匹配的队列。
如上这个设置中,我们可以看到与它绑定的两个队列的直接交换X。第一个队列用绑定键橙色绑定,第二个队列有两个绑定,一个绑定键为黑色,另一个绑定键为绿色。
在这个设置里面,一个被发布到交换器里的带有橙色路由键的消息将被路由到队列Q1中,带有黑色或绿色路由键的消息将去往队列Q2中,所有其他消息将被舍弃掉。
下面这个是多重绑定,该绑定相似与上一节的发布/订阅模式
使用相同的绑定键绑定多个队列是完全合法的。在我们的示例中,我们可以在X和Q1之间添加绑定键黑。在这种情况下,直接交换将表现为fanout类型,并将消息广播给所有匹配的队列。带有black路由键的消息将被发送到Q1和Q2。
接下来,我们将采用这个模型,代替fanout来发送消息,以这种方式进行,接收程序放可以选择性的接收消息。
该篇与上篇区别仅在于,发布和订阅方的交换器的类型变为direct,同时设置发布消息的路由键,本篇将其设置为“error”,将订阅方其中一个队列的路由键设置为“error”,另一个设置为“bug”,则运行后,只有路由键和队列名称相同的一方能够收到消息,另一个bug路由键的收不到消息。
代码如下(在上篇代码上改造,修改的代码加上了下划线以便区分):
发布方:
package com.rabbitmq.HelloWorld; import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; public class Publish { private static final String EXCHANGE_NAME = "exchangeB"; public static void main(String[] args) throws IOException, TimeoutException {
// TODO Auto-generated method stub
// 创建工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.10.185");
factory.setUsername("admin");
factory.setPassword("123456");
factory.setPort(5672);
// 创建连接
Connection connetion = factory.newConnection();
// 获得信道
Channel channel = connetion.createChannel();
// 声明交换器(声明了一个名字位exchangeA,类型修改fanout为direct类型的交换器)
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String message = "555,2,2,33,66";
// 发送消息,将第二项参数routingkey修改为error
channel.basicPublish(EXCHANGE_NAME, "error", null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
channel.close();
connetion.close();
} }
订阅方一,路由键为“error”
package com.rabbitmq.HelloWorld; import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties; public class Subscribe { private static final String EXCHANGE_NAME = "exchangeB";
private static final String QUEUE_NAME = "queueA"; public static void main(String[] args) throws IOException, TimeoutException {
// TODO Auto-generated method stub
// 创建工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.10.185");
factory.setUsername("admin");
factory.setPassword("123456");
factory.setPort(5672);
// 创建连接
Connection connetion = factory.newConnection();
// 获得信道
Channel channel = connetion.createChannel();
// 声明交换器(声明了一个名字位exchangeA,类型修改fanout为direct的交换器)
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 声明一个队列,在此采用临时队列
String queueName = channel.queueDeclare().getQueue();
// channel.queueDeclare(QUEUE_NAME, true, false, false, null);
// 队列和交换器进行绑定,并设定路由键为error
channel.queueBind(queueName, EXCHANGE_NAME, "error");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException {
// TODO Auto-generated method stub
String message = new String(body,"utf-8");
System.out.println("[x] received'"+message+"'");
}
};
channel.basicConsume(queueName, consumer);
} }
订阅方二(路由键为“bug”)
import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties; public class Subscribe { private static final String EXCHANGE_NAME = "exchangeB";
private static final String QUEUE_NAME = "queueA"; public static void main(String[] args) throws IOException, TimeoutException {
// TODO Auto-generated method stub
// 创建工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.10.185");
factory.setUsername("admin");
factory.setPassword("123456");
factory.setPort(5672);
// 创建连接
Connection connetion = factory.newConnection();
// 获得信道
Channel channel = connetion.createChannel();
// 声明交换器(声明了一个名字位exchangeA,修改fanout类型为direct类型的交换器�?
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 声明�?个队列,在此采用临时队列
String queueName = channel.queueDeclare().getQueue();
// channel.queueDeclare(QUEUE_NAME, true, false, false, null);
// 队列和交换器进行绑定,未设定路由键
channel.queueBind(queueName, EXCHANGE_NAME, "bug");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException {
// TODO Auto-generated method stub
String message = new String(body,"utf-8");
System.out.println("[x] received'"+message+"'");
}
};
channel.basicConsume(queueName, consumer);
} }
运行结果:
下面这个是在另一个项目中,没有引进日志打印的包,红色忽略即可
效果已经呈现了。
有选择的接收消息。
上一节我们使用的是fanout exchange来实现消息的发布/订阅模式,这并没有给我们带来多大的灵活性——它只能够让人盲目地进行广播。而本节我们采用direct类型的交换器来实现有选择的接收消息。直接交换器背后的路由算法很简单——消息传递到绑定键与消息的路由键完全匹配的队列。
如上这个设置中,我们可以看到与它绑定的两个队列的直接交换X。第一个队列用绑定键橙色绑定,第二个队列有两个绑定,一个绑定键为黑色,另一个绑定键为绿色。
在这个设置里面,一个被发布到交换器里的带有橙色路由键的消息将被路由到队列Q1中,带有黑色或绿色路由键的消息将去往队列Q2中,所有其他消息将被舍弃掉。
下面这个是多重绑定,该绑定相似与上一节的发布/订阅模式
使用相同的绑定键绑定多个队列是完全合法的。在我们的示例中,我们可以在X和Q1之间添加绑定键黑。在这种情况下,直接交换将表现为fanout类型,并将消息广播给所有匹配的队列。带有black路由键的消息将被发送到Q1和Q2。
接下来,我们将采用这个模型,代替fanout来发送消息,以这种方式进行,接收程序放可以选择性的接收消息。
该篇与上篇区别仅在于,发布和订阅方的交换器的类型变为direct,同时设置发布消息的路由键,本篇将其设置为“error”,将订阅方其中一个队列的路由键设置为“error”,另一个设置为“bug”,则运行后,只有路由键和队列名称相同的一方能够收到消息,另一个bug路由键的收不到消息。
代码如下(在上篇代码上改造,修改的代码加上了下划线以便区分):
发布方:
- package com.rabbitmq.HelloWorld;
- import java.io.IOException;
- import java.util.concurrent.TimeoutException;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- public class Publish {
- <u>private static final String EXCHANGE_NAME = "exchangeB";</u>
- public static void main(String[] args) throws IOException, TimeoutException {
- // TODO Auto-generated method stub
- // 创建工厂
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("192.168.10.185");
- factory.setUsername("admin");
- factory.setPassword("123456");
- factory.setPort(5672);
- // 创建连接
- Connection connetion = factory.newConnection();
- // 获得信道
- Channel channel = connetion.createChannel();
- // <u>声明交换器(声明了一个名字位exchangeA,类型修改fanout为direct类型的交换器)
- channel.exchangeDeclare(EXCHANGE_NAME, "direct");</u>
- String message = "555,2,2,33,66";
- // <u>发送消息,将第二项参数routingkey修改为error
- channel.basicPublish(EXCHANGE_NAME, "error", null, message.getBytes());</u>
- System.out.println(" [x] Sent '" + message + "'");
- channel.close();
- connetion.close();
- }
- }
订阅方一,路由键为“error”
- package com.rabbitmq.HelloWorld;
- import java.io.IOException;
- import java.util.concurrent.TimeoutException;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- import com.rabbitmq.client.Consumer;
- import com.rabbitmq.client.DefaultConsumer;
- import com.rabbitmq.client.Envelope;
- import com.rabbitmq.client.AMQP.BasicProperties;
- public class Subscribe {
- <u>private static final String EXCHANGE_NAME = "exchangeB";</u>
- private static final String QUEUE_NAME = "queueA";
- public static void main(String[] args) throws IOException, TimeoutException {
- // TODO Auto-generated method stub
- // 创建工厂
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("192.168.10.185");
- factory.setUsername("admin");
- factory.setPassword("123456");
- factory.setPort(5672);
- // 创建连接
- Connection connetion = factory.newConnection();
- // 获得信道
- Channel channel = connetion.createChannel();
- // <u>声明交换器(声明了一个名字位exchangeA,类型修改fanout为direct的交换器)
- channel.exchangeDeclare(EXCHANGE_NAME, "direct");</u>
- // 声明一个队列,在此采用临时队列
- String queueName = channel.queueDeclare().getQueue();
- // channel.queueDeclare(QUEUE_NAME, true, false, false, null);
- // 队列和交换器进行绑定,并设定路由键为error
- <u>channel.queueBind(queueName, EXCHANGE_NAME, "error");</u>
- System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
- Consumer consumer = new DefaultConsumer(channel){
- @Override
- public void handleDelivery(String consumerTag, Envelope envelope,
- BasicProperties properties, byte[] body) throws IOException {
- // TODO Auto-generated method stub
- String message = new String(body,"utf-8");
- System.out.println("[x] received'"+message+"'");
- }
- };
- channel.basicConsume(queueName, consumer);
- }
- }
订阅方二(路由键为“bug”)
- import java.io.IOException;
- import java.util.concurrent.TimeoutException;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- import com.rabbitmq.client.Consumer;
- import com.rabbitmq.client.DefaultConsumer;
- import com.rabbitmq.client.Envelope;
- import com.rabbitmq.client.AMQP.BasicProperties;
- public class Subscribe {
- <u>private static final String EXCHANGE_NAME = "exchangeB";</u>
- private static final String QUEUE_NAME = "queueA";
- public static void main(String[] args) throws IOException, TimeoutException {
- // TODO Auto-generated method stub
- // 创建工厂
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("192.168.10.185");
- factory.setUsername("admin");
- factory.setPassword("123456");
- factory.setPort(5672);
- // 创建连接
- Connection connetion = factory.newConnection();
- // 获得信道
- Channel channel = connetion.createChannel();
- // <u>声明交换器(声明了一个名字位exchangeA,修改fanout类型为direct类型的交换器�?
- channel.exchangeDeclare(EXCHANGE_NAME, "direct");</u>
- // 声明�?个队列,在此采用临时队列
- String queueName = channel.queueDeclare().getQueue();
- // channel.queueDeclare(QUEUE_NAME, true, false, false, null);
- // <u>队列和交换器进行绑定,未设定路由键
- channel.queueBind(queueName, EXCHANGE_NAME, "bug");</u>
- System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
- Consumer consumer = new DefaultConsumer(channel){
- @Override
- public void handleDelivery(String consumerTag, Envelope envelope,
- BasicProperties properties, byte[] body) throws IOException {
- // TODO Auto-generated method stub
- String message = new String(body,"utf-8");
- System.out.println("[x] received'"+message+"'");
- }
- };
- channel.basicConsume(queueName, consumer);
- }
- }
运行结果:
下面这个是在另一个项目中,没有引进日志打印的包,红色忽略即可
效果已经呈现了。
官网英文版学习——RabbitMQ学习笔记(六)Routing的更多相关文章
- 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ
鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...
- 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群
在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...
- Unity shader 官网文档全方位学习(一)
转载:https://my.oschina.net/u/138823/blog/181131 摘要: 这篇文章主要介绍Surface Shaders基础及Examples详尽解析 What?? Sha ...
- 利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录)
利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录) 作者:王可利(Star·星星) 总结: 今天学习的jQ类库的使用,代码重复的比较多需要完善.严格区分大小写,在 $(" ...
- 官网英文版学习——RabbitMQ学习笔记(二)RabbitMQ安装
一.安装RabbitMQ的依赖Erlang 要进行RabbitMQ学习,首先需要进行RabbitMQ服务的安装,安装我们可以根据官网指导进行http://www.rabbitmq.com/downlo ...
- 官网英文版学习——RabbitMQ学习笔记(三)Hello World!
参考http://www.rabbitmq.com/tutorials/tutorial-one-java.html,我们直接上代码,由于我们的RabbitMQ服务是安装在虚拟机上的,具体参考上一节. ...
- 官网英文版学习——RabbitMQ学习笔记(八)Remote procedure call (RPC)
在第四篇学习笔记中,我们学习了如何使用工作队列在多个工作者之间分配耗时的任务. 但是,如果我们需要在远程计算机上运行一个函数并等待结果呢?这是另一回事.这种模式通常称为远程过程调用或RPC. ...
- 官网英文版学习——RabbitMQ学习笔记(七)Topic
在上一篇中使用直接交换器改进了我们的系统,使得它能够有选择的进行接收消息,但它仍然有局限性——它不能基于多个条件进行路由.本节我们就进行能够基于多个条件进行路由的topics exchange学习. ...
- 官网英文版学习——RabbitMQ学习笔记(五)Publish/Subscribe
发布/订阅模式:把一个消息发送给多个消费者. 前几篇文章的思想是,我们好像看到了生产者将消息直接发送给queue,然后消费者也从queue中进行消费.其实并非如此,RabbitMQ中的消息传递模型的核 ...
随机推荐
- python3爬虫
1.爬虫的基本原理讲解 2.Urllib库的基本使用 3.Requests库的基本使用 4.正则的基本使用 5.BeautifulSoup库的使用 6.PyQuery库的使用 √ 7.Seleni ...
- Java生鲜电商平台-小程序或者APP拼团功能设计与架构实战
Java生鲜电商平台-小程序或者APP拼团功能设计与架构实战 说明:Java生鲜电商平台拼团是拉新引流的利器,将拼团运用到极致的就是拼多多,前期通过选取性价比高.实用性强的商品进行拼团,在社交圈(主要 ...
- .NET List<T>Conat vs AddRange
最大的不同在于AddRange改变了它所调用的列表,而Concat创建了一个新的List.因此它们有不同的用途. Concat也是一种适用于任何IEnumerable的扩展方法,并返回一个IEnume ...
- linux的ls -al指令
ls是“list”的意思,参数-al则表示列出所有的文件,包括隐藏文件,就是文件前面第一个字符为.的文件. 1.第一列便是这个文件的属性: #第一个属性表示这个文件时“目录.文件或链接文件等”: ...
- Linux用户和用户组管理命令
一.用户管理命令 1.useradd 创建用户或更新默认新用户的信息 使用方法 useradd [options] 用户名 选项: useradd -u 指定UID具体数值, ...
- JS弹出层制作,以及移动端禁止弹出层下内容滚动,overflow:hidden移动端失效问题
HTML <div class="layer"> <div class="menu-list"> <span>社会</ ...
- SSH、SSL与HTTPS的联系
SSH 维基百科中对SSH协议的定义如下 Secure Shell(缩写为SSH),由IETF的网络工作小组(Network Working Group)所制定:SSH为一项创建在应用层和传输层基础上 ...
- java 学习地址
数组 JAVA中数组排序小结 Java中ArrayList和LinkedList区别 在往里面插入数据时.LinkedList会比ArrayList快很多,因为前者仅仅做了一个类型的插入,而后者 ...
- 「SP2713」GSS4 - Can you answer these queries IV
传送门 Luogu 解题思路 区间开方以及区间求和. 考虑用线段树来做. 开方操作看似没有任何结合律可言,但这题有另外一个性质: 一个数的初始值不超过 \(10^{18}\) ,而这个数被开方6次左右 ...
- 【rabbitmq】Queueingconsumer被废止后老代码如何做的解决方案
amqp-client 3.x之前的rabbitmq版本有个消费者的写法是借助于Queueingconsumer的: QueueingConsumer consumer = new QueueingC ...