绑定(Bindings)

在上一个教程中,我们已经使用过绑定。你可能会记得如下代码:

channel.queueBind(queueName, EXCHANGE_NAME, "");

绑定是建立交换器和队列之间的关系。这可以简单地理解:队列对该交换器上的消息感兴趣。

为了避免与 basicPublish 方法的参数混淆,我们将其称为绑定键。下面是我们如何用一个绑定键创建一个绑定:

channel.queueBind(queueName, EXCHANGE_NAME, "black");

绑定键的意义依赖于交换器的类型。以前我们以前使用的 fanout 类型的交换器可以忽略此参数。

直接交换(Direct exchange)

我们从上一个教程的日志记录系统向所有消费者广播所有消息。现在,我们需要一个将错误日志消息写入磁盘,而不会把硬盘空间浪费警告或消息类型日志消息上。

其中,第一个队列与绑定键 orange 绑定,第二个队列有两个绑定,一个绑定键为 black,另一个绑定为 green。在这样的设置中,具有 orange 的交换器的消息将被路由到队列 Q1。具有 black 或 green 的交换器的消息将转到 Q2。所有其他消息将被丢弃。

多重绑定(Multiple bindings)

此外,使用相同的绑定键绑定多个队列是完全合法的。在我们的示例中,我们可以在 X 和 Q1 之间添加绑定键 black。在这种情况下,direct 类型的交换器将消息广播到所有匹配的队列 Q1 和 Q2。

发送日志(Emitting logs)

我们将使用 direct 类型的交换器进行日志记录系统。

channel.exchangeDeclare(EXCHANGE_NAME, "direct");

现在,我们准备发送一条消息:

channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());

为了简化代码,我们假定 ‘severity’ 是 ‘info’, ‘warning’, ‘error’ 中的一个。

订阅(Subscribing)

接收消息将像上一个教程一样工作,除了一个例外 – 我们给我们所感兴趣的严重性类型的日志创建一个绑定。

String queueName = channel.queueDeclare().getQueue();

for(String severity : argv){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}

案例实战

发送端

发送端,连接到 RabbitMQ,发送一条数据,然后退出。

public class EmitLogDirect {
private static final String EXCHANGE_NAME = "direct_logs";
private static final String[] LOG_LEVEL_ARR = {"debug", "info", "error"};
public static void main(String[] args) throws IOException, TimeoutException {
// 创建连接
ConnectionFactory factory = new ConnectionFactory();
// 设置 RabbitMQ 的主机名
factory.setHost("localhost");
// 创建一个连接
Connection connection = factory.newConnection();
// 创建一个通道
Channel channel = connection.createChannel();
// 指定一个交换器
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 发送消息
for (int i = 0; i < 10; i++) {
int rand = new Random().nextInt(3);
String severity = LOG_LEVEL_ARR[rand];
String message = "Liang-MSG log : [" +severity+ "]" + UUID.randomUUID().toString();
// 发布消息至交换器
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
}
// 关闭频道和连接
channel.close();
connection.close();
}
}

接受端

接受端,不断等待服务器推送消息,然后在控制台输出。

public class ReceiveLogsDirect {
private static final String EXCHANGE_NAME = "direct_logs";
private static final String[] LOG_LEVEL_ARR = {"debug", "info", "error"};
public static void main(String[] args) throws IOException, TimeoutException {
// 创建连接
ConnectionFactory factory = new ConnectionFactory();
// 设置 RabbitMQ 的主机名
factory.setHost("localhost");
// 创建一个连接
Connection connection = factory.newConnection();
// 创建一个通道
Channel channel = connection.createChannel();
// 指定一个交换器
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 设置日志级别
int rand = new Random().nextInt(3);
String severity = LOG_LEVEL_ARR[rand];
// 创建一个非持久的、唯一的、自动删除的队列
String queueName = channel.queueDeclare().getQueue();
// 绑定交换器和队列
// queueBind(String queue, String exchange, String routingKey)
// 参数1 queue :队列名
// 参数2 exchange :交换器名
// 参数3 routingKey :路由键名
channel.queueBind(queueName, EXCHANGE_NAME, severity);
// 创建队列消费者
final Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
}
}

现在,做一个实验,我们开启三个 ReceiveLogsDirect 工作程序:ReceiveLogsDirect1 、ReceiveLogsDirect2 与 ReceiveLogsDirect3。

ReceiveLogsDirect1

[*] Waiting for messages. To exit press CTRL+C
[*] LOG LEVEL : info
[x] Received 'Liang-MSG log : [info]0dd0ae0c-bf74-4aa9-9852-394e65fbf939'
[x] Received 'Liang-MSG log : [info]b2b032f6-e907-4c95-b676-1790204c5f73'
[x] Received 'Liang-MSG log : [info]14482461-e432-4866-9eb5-a28f4edeb47f'

ReceiveLogsDirect2

[*] Waiting for messages. To exit press CTRL+C
[*] LOG LEVEL : error
[x] Received 'Liang-MSG log : [error]493dce2a-7ce1-4111-953c-99ab2564a2d0'
[x] Received 'Liang-MSG log : [error]2446dd80-d5f0-4d39-888f-31579b9d2724'
[x] Received 'Liang-MSG log : [error]fe8219e0-5548-40ba-9810-d922d1b03dd8'
[x] Received 'Liang-MSG log : [error]797b6d0e-9928-4505-9c76-56043322b1f0'

ReceiveLogsDirect3

[*] Waiting for messages. To exit press CTRL+C
[*] LOG LEVEL : debug
[x] Received 'Liang-MSG log : [debug]c05eee3e-b820-4b69-9c3f-c2bbded85195'
[x] Received 'Liang-MSG log : [debug]4645c9ba-4070-41d7-adc9-7f8b2df1e3c8'
[x] Received 'Liang-MSG log : [debug]d3d3ad5c-8f97-49ea-8fd6-c434790e40eb'

此时,ReceiveLogsDirect1 、ReceiveLogsDirect2 与 ReceiveLogsDirect3 同时收到了属于自己级别的消息。

源代码

相关示例完整代码: https://github.com/lianggzone/rabbitmq-action

rabbitmq学习(五) —— 路由的更多相关文章

  1. (转)RabbitMQ学习之路由(java)

    http://blog.csdn.net/zhu_tianwei/article/details/40887755 参考:http://blog.csdn.NET/lmj623565791/artic ...

  2. RabbitMQ学习总结 第五篇:路由Routing

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  3. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  4. RabbitMQ学习笔记(五) Topic

    更多的问题 Direct Exchange帮助我们解决了分类发布与订阅消息的问题,但是Direct Exchange的问题是,它所使用的routingKey是一个简单字符串,这决定了它只能按照一个条件 ...

  5. RabbitMQ学习第四记:路由模式(direct)

    1.什么是路由模式(direct) 路由模式是在使用交换机的同时,生产者指定路由发送数据,消费者绑定路由接受数据.与发布/订阅模式不同的是,发布/订阅模式只要是绑定了交换机的队列都会收到生产者向交换机 ...

  6. RabbitMQ学习笔记五:RabbitMQ之优先级消息队列

    RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...

  7. RabbitMQ学习总结 第三篇:工作队列Work Queue

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  8. RabbitMQ学习总结 第一篇:理论篇

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  9. RabbitMQ学习总结 第二篇:快速入门HelloWorld

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  10. RabbitMQ学习总结 第四篇:发布/订阅 Publish/Subscribe

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

随机推荐

  1. 个推数据统计产品(个数)iOS集成实践

    最近业务方给我们部门提了新的需求,希望能一站式统计APP的几项重要数据.这次我们尝试使用的是个推(之前专门做消息推送的)旗下新推出的产品“个数·应用统计”,根据官方的说法,个推的数据统计产品通过专业的 ...

  2. 如何把你的eclipse编辑器修改成黑色的主题

  3. Java基础-进制转换

    Java基础-进制转换 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Java 程序中常用的进制 1>.十进制,由“0123456789” 这10个数字组成,逢十进一: ...

  4. Solr记录-solr基础内容

    Solr架构(体系结构) 在本章中,我们将讨论Apache Solr的架构. 下图显示了Apache Solr的体系结构的框图. Solr架构 - 构件块以下是Apache Solr的主要构建块(组件 ...

  5. 浅谈fhq treap

    一.简介 fhq treap 与一般的treap主要有3点不同 1.不用旋转 2.以merge和split为核心操作,通过它们的组合实现平衡树的所有操作 3.可以可持久化 二.核心操作 代码中val表 ...

  6. 【原创】express3.4.8源码解析之Express结构图

    前记 最近为了能够更好的搭建博客,看了开源博客引擎ghost源代码,顺道更深入的去了解express这个出名的nodejs web framework. 所以接下来一段时间对expressjs做一个源 ...

  7. 02 uni-app框架学习:设置全局样式统一每个页面的背景颜色

    1.设置全局样式可以在App.vue里面 2.在每个页面的根view 里添加一个class名叫page

  8. CSS3设置内容超过一定长度后自动折行

    在用编辑器保存的数据到数据库的时候经常是在我们的内容前后加一个P标签,但是出来之后是一行,有时候会超过边框的宽度,所以研究了如何折行,如下代码: <!DOCTYPE html> <h ...

  9. 2017/05/23 java 基础 随笔

    1.多态的好处: a.提高了代码的维护性(继承保证) b.提高了代码的扩展性(由多态保证) package com.huawei; public class Demo2 { public static ...

  10. 【ARTS】01_04_左耳听风-20181203~1209

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...