Hello World模式,告诉我们如何一对一发送和接收消息;

Work模式,告诉我们如何多管齐下高效的消费消息;

Publish/Subscribe模式,告诉我们如何广播消息

那么有没有灵活强一点的既可以高效消费,又可以同时送达多个消费者的模式?

有,这就是Routing模式,我又称之为Direct直连模式。

Routing模式

  • 一个生产者P,一个交换机X,多个消息队列Q以及多个消费者C

  • 在Exchange和Queue中,我们看到了不同的规则,也就是Routing Key

显然从图中的说明,我们就知道这是一个log日志根据级别派发消息的例子。熟悉Log日志系统的应该都知道,一般的log系统分为error、info、warn和debug等。从图中我们可以看出,将日志级别为error的定向的派发到第一个消息队列,将error、warn和info级别的日志派发到第一个消息队列。

该模型首先实现了定向派发,而不再是订阅模式那种广播式的派发。同一条消息既可以派发给一个Queue,也可以同时派发给两个或者多个Queue,这就是该模式的灵活之处。下面来看看实例

发送端

/**
* Created by jackie on 17/8/7.
*/
public class EmitLogDirect { private static final String EXCHANGE_NAME = "direct_logs"; public static void main(String[] argv) throws Exception { ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.3.161");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT); String severity = getSeverity(argv);
String message = getMessage(argv); channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes("UTF-8"));
System.out.println(" [x] Sent '" + severity + "':'" + message + "'"); channel.close();
connection.close();
} private static String getSeverity(String[] strings){
if (strings.length < 1)
return "info";
return strings[0];
} private static String getMessage(String[] strings){
if (strings.length < 2)
return "Hello World!";
return joinStrings(strings, " ", 1);
} private static String joinStrings(String[] strings, String delimiter, int startIndex) {
int length = strings.length;
if (length == 0 ) return "";
if (length < startIndex ) return "";
StringBuilder words = new StringBuilder(strings[startIndex]);
for (int i = startIndex + 1; i < length; i++) {
words.append(delimiter).append(strings[i]);
}
return words.toString();
}
}
  • String severity = getSeverity(argv);通过程序参数赋值给Routing Key,作为发送消息的规则

  • String message = getMessage(argv);通过程序参数赋值作为消息实体发送到Queue

在run configurations中配置argv

*第一个参数是要绑定key的名称,第二个参数是要发送的消息内容

  • 运行后,可以在RabbitMQ管理应用中看到exchange,但是此时没有绑定queue,所以即使发送消息也没有queue会存储或者消费。

接收端

/**
* Created by jackie on 17/8/7.
*/
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("192.168.3.161");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
String queueName = channel.queueDeclare().getQueue(); if (argv.length < 1){
System.err.println("Usage: ReceiveLogsDirect [info] [warning] [error]");
System.exit(1);
} 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);
}
}
  • channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);表示使用的exchange类型为Direct类型

  • 绑定的queue的名称也是通过program arguments指定的

这里两个参数info和error表示绑定了两个routing key,即如果发送routing key为info的消息该队列能接收到,如果发送routing key为error,该队列也能收到

运行情况

启动接收端代码,我们可以看到生成了Queue名称为amq.gen-ugjKo6t4y0PXPwoh3CeubA的队列,同时有routingKey=info和routingKey=error的绑定到了Exchange上。

这时候起送发送端给routingkey为info发送消息“hello world”,我们可以看到在接收端确实能够收到消息“hello world”,同理,这时候发送routingkey为error的消息,该队列同样能够接收到,因为队列同时绑定了两个routing key

这个就是Routing直连模式。

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

RabbitMQ入门-Routing直连模式的更多相关文章

  1. RabbitMQ入门-高效的Work模式

    扛不住的Hello World模式 上篇<RabbitMQ入门-从HelloWorld开始>介绍了RabbitMQ中最基本的Hello World模型.正如其名,Hello World模型 ...

  2. RabbitMQ入门_03_推拉模式

    我们知道,消费者有两种方式从消息中间件获取消息: 推模式:消息中间件主动将消息推送给消费者 拉模式:消费者主动从消息中间件拉取消息 推模式将消息提前推送给消费者,消费者必须设置一个缓冲区缓存这些消息. ...

  3. RabbitMQ入门-Topic模式

    上篇<RabbitMQ入门-Routing直连模式>我们介绍了可以定向发送消息,并可以根据自定义规则派发消息.看起来,这个Routing模式已经算灵活的了,但是,这还不够,我们还有更加多样 ...

  4. RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...

  5. RabbitMQ入门-消息订阅模式

    消息派发 上篇<RabbitMQ入门-消息派发那些事儿>发布之后,收了不少反馈,其中问的最多的还是有关消息确认以及超时等场景的处理. 楼主,有遇到消费者后台进程不在,但consumer连接 ...

  6. RabbitMQ入门教程(六):路由选择Routing

    原文:RabbitMQ入门教程(六):路由选择Routing 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...

  7. RabbitMQ入门:路由(Routing)

    在上一篇博客<RabbitMQ入门:发布/订阅(Publish/Subscribe)>中,我们认识了fanout类型的exchange,它是一种通过广播方式发送消息的路由器,所有和exch ...

  8. RabbitMQ入门(三)订阅模式

      在之前的文章RabbitMQ入门(二)工作队列中,我们创建了一个工作队列.工作队列背后的假设是每一项任务都被准确地传送至一个worker.在本文中,我们将会做一些不同的事情--我们将会把一个消息发 ...

  9. .NET 环境中使用RabbitMQ RabbitMQ与Redis队列对比 RabbitMQ入门与使用篇

    .NET 环境中使用RabbitMQ   在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的 ...

随机推荐

  1. Java 变量类型

    局部变量 成员变量 类变量 Java局部变量 局部变量声明在方法.构造方法或者语句块中: 局部变量在方法.构造方法.或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁: 访问修饰符不能用于局 ...

  2. docker - 启动container时出现 [warning] : ipv4 forwarding is disabled. networking will not work

    起因 今天在一台新的centos宿主机上安装docker,由于关闭了iptables,在此之后启动container的时候会出现警告: WARNING: IPv4 forwarding is disa ...

  3. 如何退出 Vim

    点击 Esc 键,; Vim 进入命令模式.然后输入: :q  退出(这是 :quit 的缩写) :q! 不保存退出(这是  :quit! 的缩写) :wq 写入文件并退出:(这是 :writequi ...

  4. php中的四种排序算法

    . 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将 ...

  5. linux下查找某个文件或目录

    以查找samba为例:find / -name samba 查找之后得到的结果集如下:/var/lib/samba/var/spool/samba/var/log/samba/usr/lib64/sa ...

  6. 一些爬虫中的snippet

    1.tornado 一个精简的异步爬虫(来自tornado的demo) #!/usr/bin/env python import time from datetime import timedelta ...

  7. Binder的工作原理浅析

    在Android开发中,Binder主要用于Service中,包括AIDL和Messenger,其中Messenger的底层实现就是AIDL,所以我们这里通过AIDL来分析一下Binder的工作机制. ...

  8. 一个DOM元素同时拥有多个类名时的样式产生冲突时 属性取决于css样式表中后读取到的属性

    如果一个DOM元素包含多个类名,其中的两个类名的属性产生冲突,并不是根据htnl中类名的顺序来决定DOM元素的属性, 而是根据css样式中的顺序来决定DOM元素的属性,它取决于css样式表中后读取到的 ...

  9. 【JS】jquery通知插件toastr

    toastr是一款非常棒的基于jquery库的非阻塞通知提示插件,toastr可设定四种通知模式:成功,出错,警告,提示,而提示窗口的位置,动画效果都可以通过能数来设置,在官方站可以通过勾选参数来生成 ...

  10. 读书笔记-Software Testing(By Ron Patton)

    Software Testing Part I:The Big Picture 1.Software Testing Background Bug's formal definition 1.The ...