RabbitMQ---交換機-Fanout-Direct

  • Publisher:生產者,不再發送消息到隊列中,而是發給交換機
  • Exchange:交換機,一方面,接收生產者發送的消息。另一方面,知道如何處理消息,例如遞交給某個特別隊列、遞交給所有隊列、或是將消息丟棄。到底如何操作,取決于Exchange的類型。
  • Queue:消息隊列也與以前一樣,接收消息、緩存消息。不過隊列一定要與交換機綁定。
  • Consumer:消費者,與以前一樣,訂閱隊列,沒有變化

Exchange(交換機)只負責轉發消息,不具備存儲消息的能力,因此如果沒有任何隊列與Exchange綁定,或者沒有符合路由規則的隊列,那么消息會丟失!

交換機的類型有四種:

  • Fanout:廣播,將消息交給所有綁定到交換機的隊列。我們最早在控制臺使用的正是Fanout交換機
  • Direct:訂閱,基于RoutingKey(路由key)發送給訂閱了消息的隊列
  • Topic:通配符訂閱,與Direct類似,只不過RoutingKey可以使用通配符
  • Headers:頭匹配,基于MQ的消息頭匹配,用的較少。

Fanout交換機

在這里插入圖片描述
簡單點來說,就是生產者把消息發給交換機,交換機根據路由(綁定規則)來轉發消息給隊列,消費者訂閱隊列,獲得消息。

Fanout,英文翻譯是扇出,我覺得在MQ中叫廣播更合適。
在廣播模式下,消息發送流程是這樣的:
image.png

  • 1) 可以有多個隊列
  • 2) 每個隊列都要綁定到Exchange(交換機)
  • 3) 生產者發送的消息,只能發送到交換機
  • 4) 交換機把消息發送給綁定過的所有隊列
  • 5) 訂閱隊列的消費者都能拿到消息
    注意:我下面的代碼都是在上一個加依賴的基礎上的,可看我上一個文檔

01利用官方文檔的

消息發送:


import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.util.Scanner;public class EmitLog {//定義交換機private static final String EXCHANGE_NAME = "fanout-exchange";public static void main(String[] argv) throws Exception {//創建連接工廠ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");//建立連接和通道try (Connection connection = factory.newConnection();Channel channel = connection.createChannel()) {//通過channel.exchangeDeclare方法聲明了一個名為EXCHANGE_NAME(即"logs")的交換機// 并指定了其類型為fanout。fanout類型的交換機會將消息廣播到所有與之綁定的隊列中。channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//發送消息Scanner scanner=new Scanner(System.in);while(scanner.hasNext()){String message = scanner.nextLine();//channel.basicPublish方法將消息發布到前面聲明的交換機中。// 注意,這里的routingKey(即第二個參數)為空字符串"",因為對于fanout類型的交換機來說,routingKey是不起作用的。channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));System.out.println(" [x] Sent '" + message + "'");}}}
}

接收:

注意一定要創建隊列,不然只有交換機沒用

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;public class ReceiveLogs {private static final String EXCHANGE_NAME = "fanout-exchange";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();//創建通道Channel channel1 = connection.createChannel();Channel channel2 = connection.createChannel();//聲明交換機channel1.exchangeDeclare(EXCHANGE_NAME, "fanout");channel2.exchangeDeclare(EXCHANGE_NAME, "fanout");//隊列的名字String queueName = "星星";//創建隊列channel1.queueDeclare(queueName, true, false, false, null);channel1.queueBind(queueName, EXCHANGE_NAME, "");String queueName1 = "晨晨";//創建隊列channel2.queueDeclare(queueName1, true, false, false, null);channel2.queueBind(queueName1, EXCHANGE_NAME, "");System.out.println(" [*] Waiting for messages. To exit press CTRL+C");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [1] Received '" + message + "'");};DeliverCallback deliverCallback2 = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [2] Received '" + message + "'");};channel1.basicConsume(queueName, true, deliverCallback, consumerTag -> { });channel2.basicConsume(queueName1, true, deliverCallback2, consumerTag -> { });}
}

請添加圖片描述
請添加圖片描述
請添加圖片描述
可以看到fanout類型,生產者發送一個消息,所有的消費者都能接收到,這個類型不用設置路由

02注解形式的:

消息發送

先在配置類中聲明交換機,隊列,以及綁定關系

   public static final String FANOUT_QUEUE_1 = "fanout.queue.1";public static final String FANOUT_QUEUE_2 = "fanout.queue.2";public static final String FANOUT_EXCHANGE = "fanout.exchange";@Beanpublic Queue fanoutQueue1() {return new Queue(FANOUT_QUEUE_1);}@Beanpublic Queue fanoutQueue2() {return new Queue(FANOUT_QUEUE_2);}@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange(FANOUT_EXCHANGE);}@Beanpublic Binding binding1() {return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());}@Beanpublic Binding binding2() {return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());}

Test類中添加測試方法:

@Test
public void testFanoutExchange() {// 交換機名稱String exchangeName = "fanout.exchange";// 消息String message = "hello, everyone!";rabbitTemplate.convertAndSend(exchangeName, "", message);
}

消息接收

在添加兩個方法,作為消費者:

@RabbitListener(queues = "fanout.queue.1")
public void listenFanoutQueue1(String msg) {System.out.println("消費者1接收到Fanout消息:【" + msg + "】");
}@RabbitListener(queues = "fanout.queue.2")
public void listenFanoutQueue2(String msg) {System.out.println("消費者2接收到Fanout消息:【" + msg + "】");
}

在這里插入圖片描述

總結

交換機的作用是什么?

  • 接收publisher發送的消息
  • 將消息按照規則路由到與之綁定的隊列
  • 不能緩存消息,路由失敗,消息丟失
  • FanoutExchange的會將消息路由到每個綁定的隊列

Direct交換機

在Fanout模式中,一條消息,會被所有訂閱的隊列都消費。但是,在某些場景下,我們希望不同的消息被不同的隊列消費。這時就要用到Direct類型的Exchange。
image.png
在Direct模型下:

  • 隊列與交換機的綁定,不能是任意綁定了,而是要指定一個RoutingKey(路由key)
  • 消息的發送方在 向 Exchange發送消息時,也必須指定消息的 RoutingKey
  • Exchange不再把消息交給每一個綁定的隊列,而是根據消息的Routing Key進行判斷,只有隊列的Routingkey與消息的 Routing key完全一致,才會接收到消息

此處我省略了官方文檔那種,直接springboot注解那種的,而且不再bean。而是全注解那種的,也是對黑馬代碼的進一步優化,不手動操作添加

下面是黑馬的案例
案例需求如圖
image.png

  1. 聲明一個名為hmall.direct的交換機
  2. 聲明隊列direct.queue1,綁定hmall.directbindingKeybludred
  3. 聲明隊列direct.queue2,綁定hmall.directbindingKeyyellowred
  4. consumer服務中,編寫兩個消費者方法,分別監聽direct.queue1和direct.queue2
  5. 在publisher中編寫測試方法,向hmall.direct發送消息

先在配置類加入下面的然后啟動一下:

    /** 基于注解的來聲明交換機和隊列及其綁定關系 */@RabbitListener( bindings = @QueueBinding(exchange = @Exchange(name = "heima.direct", type = ExchangeTypes.DIRECT),value = @org.springframework.amqp.rabbit.annotation.Queue(name = "direct.queue1"),key = {"red", "blue"}))public void rabbitListener5(String message) {System.out.println("紅藍: " + message);}@RabbitListener( bindings = @QueueBinding(exchange = @Exchange(name = "heima.direct", type = ExchangeTypes.DIRECT),value = @org.springframework.amqp.rabbit.annotation.Queue(name = "direct.queue2"),key = {"yellow","red"}))public void rabbitListener6(String message) {System.out.println("黃紅: " + message);}

消息發送

在Test類中添加測試方法:

    @Testpublic void testSendDirectExchange() {// 交換機名稱String exchangeName = "heima.direct";// 消息String message = "紅色警報!日本亂排核廢水,導致海洋生物變異,驚現哥斯拉!";// 發送消息rabbitTemplate.convertAndSend(exchangeName, "red", message);}@Testpublic void testSendDirectExchange01() {// 交換機名稱String exchangeName = "heima.direct";// 消息String message = "最新報道,哥斯拉是居民自治巨型氣球,虛驚一場!";// 發送消息rabbitTemplate.convertAndSend(exchangeName, "blue", message);}

消息接收:

    @RabbitListener(queues = "direct.queue1")public void listenDirectQueue1(String msg) {System.out.println("消費者1接收到direct.queue1的消息:【" + msg + "】");}@RabbitListener(queues = "direct.queue2")public void listenDirectQueue2(String msg) {System.out.println("消費者2接收到direct.queue2的消息:【" + msg + "】");}

先點擊測試的那個red的運行一下,在啟動項目:
在這里插入圖片描述

我們再切換為blue這個key:

你會發現,只有消費者1收到了消息:
在這里插入圖片描述
###總結
描述下Direct交換機與Fanout交換機的差異?

  • Fanout交換機將消息路由給每一個與之綁定的隊列
  • Direct交換機根據RoutingKey判斷路由給哪個隊列
  • 如果多個隊列具有相同的RoutingKey,則與Fanout功能類似

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/14513.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/14513.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/14513.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

刪除實例分割中的特定標簽

用labelme軟件對圖像進行實例分割或語義分割標注后會得到json文件,如果想要刪除某個特定標簽,可以使用如下代碼,完整代碼下載地址:代碼地址 import json import os# 要處理的json文件夾路徑 folder_path H:/json # 需要刪除的標…

如何一鍵生成多個文本二維碼?excel表格批量生碼的方法

現在很多人會將文本信息做成二維碼來展示,當有同類型內容生成大量二維碼時,可以使用將文本導入excel表格的方式,將表格中的每條數據批量生成二維碼,可以有效提升二維碼制作的速度和效率。下面就讓小編來將具體的操作步驟分享給大家…

LangChain API 2.0

轉載整理自:https://api.python.langchain.com/en/latest/langchain_api_reference.html 文章目錄 1、langchain.agentsClassesFunctions 2、langchain.callbacksClasses 3、langchain.chainsClassesFunctions 4、langchain.embeddingsClasses 5、langchain.evaluat…

二叉樹順序結構及鏈式結構

一.二叉樹的順序結構 1.定義:使用數組存儲數據,一般使用數組只適合表示完全二叉樹,此時不會有空間的浪費 注:二叉樹的順序存儲在邏輯上是一顆二叉樹,但是在物理上是一個數組,此時需要程序員自己想清楚調整…

http流式返回

HTTP流式返回(Stream)是一種服務器向客戶端傳輸數據的方式允許數據分塊發送而不是一次性發送完畢。 這樣客戶端可以在接收到第一部分數據時就開始處理,而不必等待整個響應完成。 應用場景: 2.1 業務場景:圖表的監聽&a…

手動安裝maven依賴到本地倉庫

使用mvn install命令安裝jar包到指定的倉庫。 命令如下: mvn install:install-file -Dmaven.repo.localC:\Users\liyong.m2\repository -DgroupIdcom.aspose -DartifactIdwords -Dversion18.4 -Dpackagingjar -DfileC:\Users\liyong\Desktop\jar\words-18.4.jar 解釋…

grafana + Prometheus + node-exporter + pushgateway + alertmanager的監控解決方案

業內比較著名的監控解決方案,據筆者所知,大概是三套: 一個是zabbix的解決方案,一個是prometheusgrafana,一個是ELK zabbix比較重,而且原生支持監控SNMP,自帶一個儀表盤,不需要額外…

docker redis 持久化

1、拉取redis鏡像 docker pull redis:latest 2、 mkdir /data/redis 3、填充redis.conf文件及根據需求修改相應的配置 ?通過官網地址找到對應版本的配置文件 ?將配置信息復制到redis.conf中 ?常見的修改配置 https://redis.io/docs/latest/operate/oss_and_stack/managem…

高仿果汁導航模板

參考原文:果汁導航風格模板_1234FCOM專注游戲工具及源碼例子分享 極速云

sdut pta 鏈表3(優化)-----7-3 sdut-C語言實驗-鏈表的結點插入

7-3 sdut-C語言實驗-鏈表的結點插入 分數 20 全屏瀏覽 切換布局 作者 馬新娟 單位 山東理工大學 給出一個只有頭指針的鏈表和 n 次操作,每次操作為在鏈表的第 m 個元素后面插入一個新元素x。若m 大于鏈表的元素總數則將x放在鏈表的最后。 輸入格式: 多組輸入。…

基于springboot的畢業設計系統的開發源碼

風定落花生,歌聲逐流水,大家好我是風歌,混跡在java圈的辛苦碼農。今天要和大家聊的是一款基于springboot的畢業設計系統的開發。項目源碼以及部署相關請聯系風歌,文末附上聯系信息 。 項目簡介: 畢業設計系統能夠實現…

學習通高分免費刷課實操教程

文章目錄 概要整體架構流程詳細步驟云上全平臺登錄步驟小結 概要 我之前提到過一個通過瀏覽器的三個腳本就可以免費高分刷課的文章,由于不方便拍視頻進行實操演示,然后寫下了這個實操教程,之前的三個腳本劃到文章末尾 整體架構流程 整體大…

窗口函數 | rows between …… and ……

ROWS BETWEEN ... AND ... 是 SQL 窗口函數中的一個子句&#xff0c;用于定義窗口函數操作的行范圍。窗口函數允許用戶對一組相關的記錄執行計算&#xff0c;這些記錄被稱為窗口。 基本語法 <窗口函數> OVER ( [PARTITION BY <列名>] ORDER BY <列名> [AS…

前端基礎入門三大核心之HTML篇 —— SVG的viewBox、width和height:繪制矢量圖的魔法比例尺【含代碼示例】

前端基礎入門三大核心之HTML篇 —— SVG的viewBox、width和height&#xff1a;繪制矢量圖的魔法比例尺【含代碼示例】 基本概念與作用viewBoxwidth和height 代碼示例與實踐基礎示例動態調整示例 不同角度的使用思路保持比例縮放自動適應容器 實際問題與解決方案結語與討論 在前…

華為云之Zabbix監控平臺部署實踐

華為云之Zabbix監控平臺部署實踐 一、本次實踐介紹1.1 實踐環境簡介1.3 本次實踐完成目標 二、 相關服務介紹2.1 華為云ECS云服務器介紹2.2 Zabbix介紹 三、環境準備工作3.1 預置實驗環境3.2 查看預置環境信息 四、登錄華為云4.1 登錄華為云4.2 查看ECS狀態4.3 連接ECS彈性云服…

力扣HOT100 - 287. 尋找重復數

解題思路&#xff1a; 快慢指針 第一步&#xff0c;慢指針每次移動一步&#xff0c;快指針每次移動兩步&#xff0c;直到它們相遇。這一步保證了它們在環中相遇。 接下來&#xff0c;將其中一個指針&#xff08;快指針或慢指針&#xff09;重置到起點&#xff08;即數組的第一…

SpringBoot實現郵箱驗證碼

自行創建一個SpringBoot項目 導入SpringBoot所需要的郵箱驗證碼的包 <!--郵件發送--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId><version>2.6.1</version>…

前后端部署筆記

windows版&#xff1a; 如果傻唄公司讓用win電腦部署&#xff0c;類似于我們使用筆記本做局域網服務器&#xff0c;社內使用。 1.安裝win版的nginx、mysql、node、jdk等 2.nginx開機自啟參考Nginx配置及開機自啟動&#xff08;Windows環境&#xff09;_nginx開機自啟動 wind…

UPPAAL使用方法

UPPAAL使用方法 由于剛開始學習時間自動機及其使用方法&#xff0c;對UPPAAL使用不太熟悉&#xff0c;網上能找到的教程很少&#xff0c;摸索了很久終于成功實現一個小例子&#xff0c;所以記錄一下詳細教程。 這里用到的例子參考【UPPAAL學習筆記】1&#xff1a;基本使用示例…

專業級潤滑油,一站式批發服務

要為機械設備提供持久穩定的動力保障嗎&#xff1f;選擇我們的專業級潤滑油&#xff0c;讓您的設備運轉更順暢&#xff0c;效率更高。 我們專業從事潤滑油批發多年&#xff0c;以優質的產品、合理的價格和完善的服務贏得了廣大客戶的信賴。無論是汽車、機械還是工業設備&#x…