路由

本次我们将通过路由将信息发送到指定的队列中,将消息发送给指定的队列需要在转发器和队列之间建立一个routeKey

绑定

在以前的例子中,我们已经创建了绑定。你可能会记得如下代码:

channel.queueBind(queueName,EXCHANGE_NAME,“”);
以上代码是针对于fanout转发器,这种类型的转发器会广播消息到所以与它绑定了的队列,会忽略第三个参数
本例将使用direct类型的转发器,这种转发器需要指定routeKey,告诉这个转发器,消息应当转发给哪个队列
channel.queueBind(queueName,EXCHANGE_NAME,“black”);

以上代码中的第三个参数black就是routekey。

routeKey的含义取决于转发类型。第三个参数是routeKey,如果转发器类型是fanout,那么这个routeKey会被忽略。

direct转发器

直接转发器的路由算法很简单 - 消息只会传递给routeKey匹配的队列。如下图:

上图中,我们可以看到直接转发器X与两个绑定的队列。第一个队列与routeKey橙色绑定,第二个队列有两个绑定,一个routeKey为黑色,另一个routeKey为绿色。

生产者发送消息给orange这个routeKey,那么消息会被转发到Q1这个队列,如果routeKey是black和green,那么就会转发到Q2这个队列。

多重绑定

使用相同的routeKey绑定多个队列是完全合法的。在我们的示例中,我们可以在X和Q1之间添加routeKey black。在这种情况下,direct转发器将表现得像fanout转发器,并将消息广播到所有匹配的队列。具有routeKey为black的消息将传送到 Q1和Q2。

提交日志

本次实例将消息发送到direct转发器,转发器根据routeKey决定消息应当发往哪个队列,我们将以日志的严重程度(error, warning, info)作为routeKey。

我们需要定义一个直接转发器:

channel.exchangeDeclare(EXCHANGE_NAME,“direct”);

我们准备发送消息:

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

severity为error,info,warning之一。

订阅

创建一个排他,自动删除,随机命名,非持久的队列:

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

使用severity绑定队列
for(String severity:argv){
channel.queueBind(queueName,EXCHANGE_NAME,severity);
}

下图为绑定示意图:

EmitLogDirect.java类的代码:

 package com.rabbitMQ;

 import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; public class EmitLogDirect { private static final String EXCHANGE_NAME = "direct_logs"; public static void main(String[] argv) throws java.io.IOException, Exception { ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME, "direct"); String severity = getSeverity(argv);
String message = getMessage(argv);
// 第二参数为routeKey,指定消息应当发给哪个队列
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
System.out.println(" [x] Sent '" + severity + "':'" + message + "'"); channel.close();
connection.close();
} private static String getSeverity(String[] argv) { if (argv.length == ) { return "info";
}
String str = argv[]; String routeKey = str.replaceAll("=.*", ""); return routeKey;
} private static String getMessage(String[] argv) {
if (argv.length == ) { return "mistake happen!!!";
}
String str = argv[];
String message = str.replaceAll(".*=", "");
return message;
} }

ReceiveLogsDirect.java的代码:

 package com.rabbitMQ;

 import com.rabbitmq.client.*;

 import java.io.IOException;

 public class ReceiveLogsDirect {

   private static final String EXCHANGE_NAME = "direct_logs";

   public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String queueName = channel.queueDeclare().getQueue(); if (argv.length < ){
System.err.println("Usage: ReceiveLogsDirect [info] [warning] [error]");
System.exit();
} //给转发器和队列之间建立routeKey,传入info,warning,error等级
for(String severity : argv){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}
System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); 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 '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
}
}

启动ReceiveLogsDirect.java,给它传error,warning,info参数

再次启动ReceiveLogsDirect.java,给它传warning,info参数

启动EmitLogDirect.java,给它传error=some error happend

那么只有第一个ReceiveLogsDirect.java才能接收到消息,

再次启动EmitLogDirect.java,给它传info=Send message

那么两个ReceiveLogsDirect.java都会接收到消息。

rabbitMQ_routing(四)的更多相关文章

  1. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  2. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  3. 如何一步一步用DDD设计一个电商网站(四)—— 把商品卖给用户

    阅读目录 前言 怎么卖 领域服务的使用 回到现实 结语 一.前言 上篇中我们讲述了“把商品卖给用户”中的商品和用户的初步设计.现在把剩余的“卖”这个动作给做了.这里提醒一下,正常情况下,我们的每一步业 ...

  4. 从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点)

    从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...

  5. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  6. “四核”驱动的“三维”导航 -- 淘宝新UI(需求分析篇)

    前言 孔子说:"软件是对客观世界的抽象". 首先声明,这里的"三维导航"和地图没一毛钱关系,"四核驱动"和硬件也没关系,而是为了复杂的应用而 ...

  7. 【翻译】MongoDB指南/CRUD操作(四)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选 ...

  8. HTML 事件(四) 模拟事件操作

    本篇主要介绍HTML DOM中事件的模拟操作. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4.  ...

  9. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

随机推荐

  1. CentOS7.x mini安装OVS

    命令均在root用户下运行: 一.关闭防护墙及selinux sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config setenfor ...

  2. kubernetes实战篇之创建一个只读权限的用户

    系列目录 上一节我们讲解到了如何限制用户访问dashboard的权限,这节我们讲解一个案例:如何创建一个只读权限的用户. 虽然可以根据实际情况灵活创建各种权限用户,但是实际生产环境中往往只需要两个就行 ...

  3. 【设计模式】行为型07备忘录模式(Memento Pattern)

    参考地址:http://www.runoob.com/design-pattern/memento-pattern.html 对原文总结调整,以及修改代码以更清晰的展示: 备忘录模式(快照模式):   ...

  4. yii中find()指定条件

    find()查找指定的条件 $modelName::model->find(); 使用条件对象 $criteria = new CDbCriteria(); $criteria->sele ...

  5. java finally块执行时机分析

    java里 finally 关键字通常与try catch块一起使用.用来在方法结束前或发生异常时做一些资源释放的操作.最近也看到网上有一些讨论try catch finally关键词执行的顺序的文章 ...

  6. 什么是JS跨域请求

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  7. 设计模式-享元模式(Flyweight)

    享元模式是构造型模式之一,它通过与其他类似对象共享数据来减少内存占用 角色和职责: 1.抽象享元角色()-Person:   享元角色的公共接口 2.具体享元角色()-Teacher: 抽象享元角色的 ...

  8. 字符串匹配Boyer-Moore算法:文本编辑器中的查找功能是如何实现的?---这应该讲的最容易懂的文章了!

    关于字符串匹配算法有很多,之前我有讲过一篇 KMP 匹配算法:图解字符串匹配 KMP 算法,不懂 kmp 的建议看下,写的还不错,这个算法虽然很牛逼,但在实际中用的并不是特别多.至于选择哪一种字符串匹 ...

  9. iOS 国际化 (国际化文字内容不改变,app名字国际化,一键切换语言)

    首先我们要分三个步骤讲解怎么一步步实现app名字国际化.内容国际化.一键切换国际化的: 一.app设置内容或者可以说是app名字或者可以说Info.Plist中的东西国际化  app名字国际化  1. ...

  10. 不使用 ASR 将虚机还原到另一个数据中心

    背景 在 Azure 上可能会遇到一个场景是将一台虚机搬到另一台数据中心,在不借助 ASR 的情况下我们该如何做? 因为 ASR 在云上更多的场景是用于灾备到异地.对于虚机的相关信息主要的是磁盘和网络 ...