路由

本次我们将通过路由将信息发送到指定的队列中,将消息发送给指定的队列需要在转发器和队列之间建立一个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. HTML连载7-表单练习

    昨天因为晚上有事情,未更新,但是今天中午发也不晚,因为是同一天只是时间早晚而已,因此今日傍晚还将更新一次,废话不多说. 1.表单的综合练习,我们要创建一个综合的注册页面.运用到我们前面所学的所有知识. ...

  2. 使用 Cake 推送 NuGet 包到 AzureDevops 的 Artifacts 上

    前言 大家好,我最近在想如何提交代码的时候自动的打包 NuGet 然后发布到 AzureDevOps 中的 Artifacts,在这个过程中踩了很多坑,也走了很多弯路,所以这次篇文章就是将我探索的结果 ...

  3. Python-基本数据类型(list,tuple)

    一. 列列表 1.1   列列表的介绍 列表是python的基础数据类型之⼀一,其他编程语言也有类似的数据类型. 比如JS中的数 组, java中的数组等等. 它是以[ ]括起来, 每个元素用' , ...

  4. AppBoxFuture: 大数据表分区的3种策略

      之前的文章"分而治之"在介绍大表分区时,作者尚未实现不同的分区策略,即只能按指定的分区键进行分区.这次作者完善了一下分区策略,在规划大表分区时可以按Hash或者时间范围进行分区 ...

  5. 对def函数的参数认识

    转载:https://www.cnblogs.com/Guido-admirers/p/6068702.html 如何理解函数的形式参数*args,**kwargs 形参*args的输出形式为tupl ...

  6. SSM(六)JDK动态代理和Cglib动态代理

    1.Cglib动态代理 目标类: package cn.happy.proxy.cglib; public class Service { public Service() { System.out. ...

  7. java中关于IO流的知识总结(重点介绍文件流的使用)

    今天做软件构造实验一的时候,用到了java文件流的使用,因为之前学的不是很踏实,于是决定今天好好总结一下, 也方便以后的回顾. 首先,要分清IO流中的一些基础划分: 按照数据流的方向不同可以分为:输入 ...

  8. SQLPLUS执行PL/SQL语句块

    1.首先登录Oracle HR schema: 2.对于PL/SQL程序,分号表示语句的结束:而使用 "."  号表示整个语句块的结束,也可以省略.按回车键后,该语句块不会执行,即 ...

  9. PATB 1015. 德才论 (25)

    1015. 德才论 (25) 比较函数折腾好久,最后还因为cout,printf的区别而超时,超时是因为cout输出效率低. 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 ...

  10. 18 | 眼前一亮:带你玩转GUI自动化的测试报告