官网英文版学习——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中的消息传递模型的核 ... 
随机推荐
- 记录一次Nginx使用第三方模块fair导致的线上故障排错
			一.问题 今天发现有一台服务器的内存飙升,然后有预警,立即排查,发现该服务内存使用达到了 2G ,询问开发,当天是否有活动,被告知没有,登陆 Pinpoint 发现该服务是有两台机器,并且所有的访问都 ... 
- Python 操作rabbitmq中的confirm模式的错误
			今天使用rabbitmq的confirm模式,书上介绍的是pika版本是0.9.6,但是我用的是别的版本,发现这样的错误 Traceback (most recent call last): Fil ... 
- 图形数据写入数据库,Filletream
			图形数据写入数据库 用FileStream对象读模式打开图形文件 Dim 文件对象 As New FileStream(图形文件名, FileMode.Open, FileAccess.Read) 定 ... 
- 常用的UI控件
			关于本文:作为一名iOS软件工程师,熟练规范的使用常用的UI控件是必备的基础技能. 指示器(UIActivityIndicatorView)----转动的等待小菊花 提醒对话框(UIAlertView ... 
- antd组件实现上传证书
- 认识系统服务 (daemons)
			daemon(守护进程:后台程序)与服务: 系统为了某些功能必须要提供一些服务 (不论是系统本身还是网络方面),这个服务就称为 service .但是 service 的提供总是需要程序的运作 ... 
- JS弹出层制作,以及移动端禁止弹出层下内容滚动,overflow:hidden移动端失效问题
			HTML <div class="layer"> <div class="menu-list"> <span>社会</ ... 
- modelsim10.4环境变量的设置
			在用户变量中设置,注意路径还要包括license.txt 点击高级属性设置 点击环境变量 在用户变量一件名为:MGLS_LICENSE_FILE的变量 点击确定 
- Kotlin 学习 (一)
			开始学习kotlin mark入门资料一篇: Kotlin入门第一课:从对比Java开始 未完待续... 
- 使用Hibernate+MySql+native SQL的BUG,以及解决办法
			本来是mssql+hibernate+native SQL 应用的很和谐 但是到了把mssql换成mysql,就出了错(同样的数据结构和数据). 查询方法是: String sql = " ... 
