【RabbitMQ】三種型別交換器 Fanout,Direct,Topic
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的交換器型別佇列MQ型別
- RabbitMQ系列(三)RabbitMQ交換器Exchange介紹與實踐MQ
- 4.RabbitMQ 4種交換模式MQ模式
- RabbitMQ 入門(六)SpringAMQP五種訊息型別(釋出訂閱模式和Fanout Exchange )MQSpringGAM型別模式
- C#使用RabbitMq佇列(Sample,Work,Fanout,Direct等模式的簡單使用)C#MQ佇列模式
- RabbitMQ - SpringBoot 案例 - fanout 模式MQSpring Boot模式
- 三種交換變數的方法變數
- 二層交換機和三層交換機的區別
- 【RabbitMQ】fanout type exchange example in golangMQGolang
- RabbitMQ 入門案例 - fanout 模式MQ模式
- 再看rabbitmq的交換器和佇列的關係MQ佇列
- RabbitMQ - SpringBoot 案例 - direct 模式MQSpring Boot模式
- RabbitMQ - SpringBoot 案例 - topic 模式MQSpring Boot模式
- 交換兩個資料的三種方法
- 【RabbitMQ】direct type exchange example in golangMQGolang
- 【RabbitMQ】topic type exchange example in golangMQGolang
- 三種輔導型別型別
- 乙太網交換機埠型別有哪些?型別
- 接入交換機、匯聚交換機、核心交換機的區別
- RabbitMQ 入門(三)SpringAMQP訊息轉換器MQSpringGAM
- 利聯科技:揚州BGP伺服器的華為三層交換機和二層交換機的區別伺服器
- 【訊息佇列】RabbitMq-交換機模型佇列MQ模型
- SpringBoot整合RabbitMQ實戰附加死信交換機Spring BootMQ
- 網管型交換機和非網管交換機區別在哪兒?記住下面幾點
- RabbitMQ的使用--以topic路由為例MQ路由
- RabbitMQ Go客戶端教程5——topicMQGo客戶端
- Redis 三種特殊資料型別Redis資料型別
- 資料更改事件的三種型別事件型別
- 06-redis的三種特殊型別Redis型別
- sap table 分為三種型別(轉)型別
- 資料中心代理的三種型別型別
- SAP QM 三種型別的Physical Sample型別
- VLAN與三層交換機
- 工業級交換機和網路級交換機區別?
- 工業交換機與商業交換機區別對比
- 全國產交換機、軍用交換機與普通交換機到底有啥區別?
- 自學PHP筆記 (三) 型別轉換PHP筆記型別
- 自學PHP筆記(三) 型別轉換PHP筆記型別
- golang 中的四種型別轉換總結Golang型別