出处: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(转)的更多相关文章

  1. RabbitMQ三种Exchange模式(fanout,direct,topic)的特性 -摘自网络

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  2. RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  3. RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较(转)

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  4. [转]RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  5. RabbitMQ三种Exchange模式

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  6. 【转】RabbitMQ三种Exchange模式

    [转]RabbitMQ三种Exchange模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四 ...

  7. 8、RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较

    RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较 RabbitMQ中,除了Simple Queue和Work Queue之外的所有生产者提交的消息都由Exc ...

  8. 链路层三种类型的MAC地址

    若需要转载,请注明出处. 我们知道,链路层都是以MAC地址来进行通信双方的地址标识的,如下图:在应用中根据接收方的多寡来进行划分,可分为以下三种: 单播(Unicast) 多播(Multicast) ...

  9. matlab for循环的三种类型

    学习了一半了,发现一个好网站,就是我想写这篇博客用的,网络真是个好东西!纪念下国庆啦 网址:http://www.yiibai.com/matlab/matlab_for_loop.html ---- ...

随机推荐

  1. Codeforces Beta Round #49 (Div. 2)

    Codeforces Beta Round #49 (Div. 2) http://codeforces.com/contest/53 A #include<bits/stdc++.h> ...

  2. EXCEL中去掉撇号的操作方法

    ▲数字前带撇号 选定想去掉撇号的列,然后选“数据”→“分列”在弹出的 对话框中单击“下一步” ,在“文本标识符号”处选择“'” 单击 “完成”即可

  3. Mac git 终端使用

    终端有这个提示,这个按照命令 输入你的 git账号和邮箱就可以, 不然一直出这个提示 Your name and email address were configured automatically ...

  4. webpack(二) 根据模板生成简单的html文件

    (一)使用webpack 根据模板生成HTML,首先需要安装插件 html-webpack-plugin. 在工程文件夹安装插件 命令如下: npm install html-webpack-plug ...

  5. SAP请求号的传输

    SAP传输目的: SAP传输目的是把开发机中的程序或对象传输到对应的测试机或生成机中,保持各系统的同步性,方便测试和最后的部署! SAP求情号传输的步骤: 1.创建一个请求号 2.用SE10进入如下界 ...

  6. js阻止a标签默认事件的几种方法

    方法/步骤    疑问 打开编辑器,新建html并加入a标签,如图所示,小编想点击a标签时执行pop函数同时禁止a标签的默认的href跳转,该如何阻止呢?  方法一 要阻止a标签跳转,可以改变href ...

  7. 为Linux虚拟机设置网络

    安装虚拟机的时候为了使用方便我们除了需要设置静态ip为了能够让虚拟机也能够上网我们需要设置虚拟机网络 当然也可以使用虚拟机和主机共享上网,这个比较简单,这里就不说了,现在我们来通过桥接的方式为虚拟机设 ...

  8. KubeletNotReady runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

    1.  mkdir -p /etc/cni/net.d 2. vi 10-flannel.conflist {  "name": "cbr0",  " ...

  9. Numpy 基础运算

    numpy的几种运算 1.一维矩阵运算 >>> import numpy as np >>> a=np.array([10,20,30,40]) # array([ ...

  10. linux 使用笔记6

    ---恢复内容开始--- 1.内容追加 把一个文件的内容追加到另一个文件中: cat first.txt >> second.txt//追加到second.txt文件的末端    cat ...