【RabbitMQ】三种类型交换器 Fanout,Direct,Topic(转)
出处:https://blog.csdn.net/fxq8866/article/details/62049393
RabbitMQ服务器会根据路由键将消息从交换器路由到队列中,如何处理投递到多个队列的情况?这里不同类型的交换器起到了重要的作用。分别是fanout,direct,topic,每一种类型实现了不同的路由算法。
Fanout Exchange
不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。

生产者
package com.dynamic.rabbitmy.ps;
/**
* Created by fxq on 2017/3/10.
*/
import com.dynamic.rabbitmy.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 生产者
*/
public class Send {
private final static String EXCHANGE_NAME="test_exchange_fanout";
public static void main(String[] args) throws Exception{
//获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明交换器
channel.exchangeDeclare(EXCHANGE_NAME,"fanout");//fanout交换器
//消息内容
String message = "商品已经删除,id=1000";
channel.basicPublish(EXCHANGE_NAME,"",null,message.getBytes());
System.out.println(" [x] Sent'"+message+"'" );
channel.close();
connection.close();
}
}
消费者
package com.dynamic.rabbitmy.ps;
/**
* Created by fxq on 2017/3/10.
*/
import com.dynamic.rabbitmy.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
/**
* 消费者
*/
public class Recv
{
private final static String QUEUE_NAME="test_queue_fanout_1";
private final static String EXCHANGE_NAME="test_exchange_fanout";
public static void main(String[] args) throws Exception{
//获取到连接以及通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//绑定队列到交换器
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,""); //不设置路由键
//统一时刻服务器只会发一条消息给消费者;
channel.basicQos(1);
//定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
//监听队列,手动返回完成
channel.basicConsume(QUEUE_NAME,false,consumer);
//获取消息
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" 前台系统:'" + message + "'");
Thread.sleep(10);
//手动返回
channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
}
}
}
Direct Exchange
处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “test”,则只有被标记为“test”的消息才被转发,不会转发test.aaa,也不会转发dog.123,只会转发test。

生产者:
package com.dynamic.rabbitmy.routing;
/**
* Created by fxq on 2017/3/10.
*/
import com.dynamic.rabbitmy.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 生产者
*/
public class Send {
private final static String EXCHANGE_NAME="test_exchange_direct";
public static void main(String[] args) throws Exception{
//获取到连接以及通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明exchange
channel.exchangeDeclare(EXCHANGE_NAME,"direct");
//消息内容
String message = "删除商品,id = 1001";
channel.basicPublish(EXCHANGE_NAME,"delete",null,message.getBytes()); //此处delete为路由键;
System.out.println(" [x] Sent '"+ message+"'");
channel.close();
connection.close();
}
}
生产者:
package com.dynamic.rabbitmy.routing;
/**
* Created by fxq on 2017/3/10.
*/
import com.dynamic.rabbitmy.util.ConnectionUtil;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
/**
* 消费者1
*/
public class Recv {
private final static String QUEUE_NAME="test_queue_direct_1";
private final static String EXCHANGE_NAME="test_exchange_direct";
public static void main(String[] args) throws Exception{
//获取连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//绑定队列到交换机;
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"update"); //匹配路由键为update
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"delete"); //匹配路由键是delete
//同一时刻服务器只会发送一条消息给消费者;
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
//监听队列,手动返回完成
channel.basicConsume(QUEUE_NAME,false,consumer);
//获取消息
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("前台系统:'"+message+"'");
Thread.sleep(10);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
}
}
}
该绑定在交换器上的队列,它可以匹配delete,update的路由键,但不是能匹配insert;必须和生产者声明是一模一样;
Topic Exchange
将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。

生产者:
package com.dynamic.rabbitmy.topic;
/**
* Created by fxq on 2017/3/10.
*/
import com.dynamic.rabbitmy.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 发送者
*/
public class Send {
private final static String EXCHANGE_NAME="test_exchange_topic" ;
public static void main(String[] args) throws Exception{
//获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明exchange
channel.exchangeDeclare(EXCHANGE_NAME,"topic");
//消息内容
String message = "插入商品,id=100";
//发布消息
channel.basicPublish(EXCHANGE_NAME,"item.insert",null,message.getBytes());
System.out.println(" [x] Sent '"+message + "'");
channel.close();
connection.close();
}
}
消费者:
package com.dynamic.rabbitmy.topic;
import com.dynamic.rabbitmy.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.sun.media.sound.SF2InstrumentRegion;
/**
* Created by fxq on 2017/3/10.
*/
public class Recv2 {
private final static String QUEUE_NAME="test_queue_topic2";
private final static String EXCHANGE_NAME="test_exchange_topic" ;
public static void main(String[] args) throws Exception{
//获得连接和mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明通道
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//绑定exchange
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"item.#"); //使用item.# 匹配所有的以item开头的
//同一时刻服务器只能发送一条消息给消费者;
channel.basicQos(1);
//声明消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
//监控队列,设置手动完成
channel.basicConsume(QUEUE_NAME,false,consumer);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("搜索系统 '" + message + "'");
Thread.sleep(10);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
}
}
}
以上就是三种交换器的类型以及他们的使用场景,基于消息的路由键和交换器的类型,服务器会决定将消息投递到那个队列中。
【RabbitMQ】三种类型交换器 Fanout,Direct,Topic(转)的更多相关文章
- RabbitMQ三种Exchange模式(fanout,direct,topic)的特性 -摘自网络
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
- RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
- RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较(转)
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
- [转]RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
- RabbitMQ三种Exchange模式
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...
- 【转】RabbitMQ三种Exchange模式
[转]RabbitMQ三种Exchange模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四 ...
- 8、RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较
RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较 RabbitMQ中,除了Simple Queue和Work Queue之外的所有生产者提交的消息都由Exc ...
- 链路层三种类型的MAC地址
若需要转载,请注明出处. 我们知道,链路层都是以MAC地址来进行通信双方的地址标识的,如下图:在应用中根据接收方的多寡来进行划分,可分为以下三种: 单播(Unicast) 多播(Multicast) ...
- matlab for循环的三种类型
学习了一半了,发现一个好网站,就是我想写这篇博客用的,网络真是个好东西!纪念下国庆啦 网址:http://www.yiibai.com/matlab/matlab_for_loop.html ---- ...
随机推荐
- python 库安装方法及常用库
python 库安装方法及常用库 python库安装方法: 方法一:setpu.py 1.下载库压缩包,解压,记录下路径:*:/**/……/ 2.运行cmd,切换到*:/**/……/目录下 3.运行s ...
- 在CentOS7.4上手动编译安装Mysql-5.7.20
实验环境:CentOS 7.4 mysql软件: mysql-boost-5.7.20.tar.gz 1.安装编译工具 yum -y install \ncurses \ncurses-devel \ ...
- ajax请求跨域
解决方式 1: 解决方式 2: 服务端: package ceshi_utils; import java.util.*; import com.xwhb.utils.encrypt.CipherUt ...
- 【python】入门指南1
基础的数据结构:int, float, string 注意:python入门系列的文章的示例均使用python3来完成. #!/bin/python a = 1 b = 1.0 c = 'string ...
- Delphi中记录体做为属性的赋值方法
1. 起源 此问题源于[秋风人事档案管理系统]用Delphi XE重编译中所发现. 快十年了,当初Delphi 7所编写项目,想用Delphi XE重新编译,并打算做为Free软件发布,编译错误中发现 ...
- AngularJS——第3章 指令
第3章 指令 所谓指令就是AngularJS自定义的HTML属性或标签,这些指令都是以ng-做为前缀的,例如ng-app.ng-controller.ng-repeat等. 3.1 内置指令 ng-a ...
- angular2.0学习笔记6.编程风格指南
1.组件的类名应该是大驼峰形式,并且以Component结尾. 因此英雄详情组件的类名是HeroDetailComponent. 组件的文件名应该是小写中线形式,每个单词之间用中线分隔,并且以.com ...
- linux中的定时任务创建
1.查看root用户身份下正常运行的定时任务 crontab -l -u XXX 列出XXX用户的所有定时任务,如有没有会提示 no crontab for XXX列出所有的用户:cat /etc/p ...
- django DEBUG=False
在django的settings中. 将DEBUG 设置为False. 会出现 #python manage.py runserver 8888 CommandError: You must set ...
- Servlet会话管理二(Cookie)
Cookie是在HTTP协议下,将服务器传递给浏览器的的少量信息保存到浏览器客户端的一种技术,通过这种技术,即使在浏览器被关闭或链接中断的情况下,用户仍可以维护Cookie中的数据. Cookie是经 ...