主頁 >  其他 > 小小MQ,知識點竟然這么多???

小小MQ,知識點竟然這么多???

2021-09-07 07:55:16 其他

小小MQ,知識點竟然這么多???

    • 一、MQ的基本概念
      • 1.MQ概述
    • 二、MQ的優勢
      • 1.應用解耦
      • 2.異步提速
      • 3.削峰填谷
    • 三、MQ的劣勢
      • 系統可用性降低
      • 系統復雜度提高
    • 四、常見的MQ產品
    • 五、RabbitMQ 介紹
      • 1.RabbitMQ 簡介
        • 1.1 Producer(生產者) 和 Consumer(消費者)
        • 1.2 Exchange(交換器)
        • 1.3 Queue(訊息佇列)
        • 1.4 Broker(訊息中間件的服務節點)
        • 1.5 Exchange Types(交換器型別)
          • ① fanout
          • ② direct
          • ③ topic
          • ④ headers(不推薦)
      • 2.總結
      • 3.Windows本地環境安裝RabbitMQ
        • 3.1 下載Erlang
        • 3.2 安裝RabbitMQ(3.9.5)
        • 3.3啟動
        • 3.4安裝管理插件
        • 5.訪問后臺
      • 4.從一個簡單的例子認識RabbitMQ
        • 1.示例
        • 2.重復消費
          • 解決方案
        • 3.訊息丟失
        • 4.訊息積壓
        • 5.MQ高可用
    • 六、原始碼分析
      • 1.回顧設計模式
        • 1.1 工廠方法模式
        • 1.2 抽象工廠模式
        • 1.3 建造者模式
      • 2.理解RabbitMQ與客戶端的資料互動
      • 3.帶著問題去看代碼
        • 3.1 訊息是如何入隊的?
        • 3.2 訊息是如何被消費的?
        • 3.3 客戶端是如何建立連接的?
        • 3.4 channel是什么?
        • 3.5 RabbitMQ是如何實作異步的?
        • 3.6 RabbitMQ如何確保訊息不會丟失?Ack
        • 3.7 為什么消費者在啟動后會自動消費佇列中的訊息?
        • 3.8 消費者接收到消費資訊,停止運行消費者后,會繼續執行消費行為?
      • 4.核心思想

一、MQ的基本概念

1.MQ概述

MQ全稱Message Queue(訊息佇列),是在訊息的傳輸程序中保存訊息的容器,多用于分布式系統之間進行通信,
常見的服務通信:
在這里插入圖片描述
加入MQ后:
在這里插入圖片描述

二、MQ的優勢

1.應用解耦

服務與服務之間不再約定協議而對接介面,而是通過生產者/消費者的模式讓中間件的MQ來對接兩邊的資料通信實作解耦合(擴展性更強),
常見的服務通信:
(img-6bqQbeN2-1630732260464)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20210904002931751.png)]加入MQ后:
在這里插入圖片描述

2.異步提速

常見的服務通信:
需要阻塞成功獲取到回應狀態在寫入資料到資料庫,阻塞同步往下執行,
在這里插入圖片描述加入MQ后:
在這里插入圖片描述

3.削峰填谷

常見的服務通信:當一瞬間有5000個請求給到服務器時,服務器最大能處理1000請求,受不了了當場去世,
在這里插入圖片描述

加入MQ后:
先把請求丟到佇列中等待處理,系統每秒從mq中拉取1000個請求進行處理(剛好卡在能處理的1000個,真實壓榨案例),這樣就變成了從1秒鐘處理5000個請求的高峰期,拆分成了 5秒鐘,每秒鐘處理1000請求的平緩處理器,哦不,是滿載處理器,
在這里插入圖片描述

根據下面的圖所示,確實高峰期被削掉了
在這里插入圖片描述

三、MQ的劣勢

系統可用性降低

系統引入的外部依賴越多,系統穩定性越差,一旦MQ宕機,就會對業務產生影響,如何保證MQ的高可用?

系統復雜度提高

MQ的加入大大增加了系統的復雜度,以前系統間是同步的遠程呼叫,現在是通過MQ進行的異步呼叫,如何保證訊息不背丟失等等,

四、常見的MQ產品

MQ是一種抽象的概念,衍生了各種基于其思想的實作,如常見的:RabbitMQ,RocketMQ,Kafka,
在這里插入圖片描述

五、RabbitMQ 介紹

建議直接看總結,下面的知識可以慢慢品(以下參考Guide哥的)

1.RabbitMQ 簡介

RabbitMQ 是采用 Erlang 語言實作 AMQP(Advanced Message Queuing Protocol,高級訊息佇列協議)的訊息中間件,它最初起源于金融系統,用于在分布式系統中存盤轉發訊息,

RabbitMQ 發展到今天,被越來越多的人認可,這和它在易用性、擴展性、可靠性和高可用性等方面的卓著表現是分不開的,RabbitMQ 的具體特點可以概括為以下幾點:

  • 可靠性: RabbitMQ使用一些機制來保證訊息的可靠性,如持久化、傳輸確認及發布確認等,
  • 靈活的路由: 在訊息進入佇列之前,通過交換器來路由訊息,對于典型的路由功能,RabbitMQ 己經提供了一些內置的交換器來實作,針對更復雜的路由功能,可以將多個交換器系結在一起,也可以通過插件機制來實作自己的交換器,這個后面會在我們將 RabbitMQ 核心概念的時候詳細介紹到,
  • 擴展性: 多個RabbitMQ節點可以組成一個集群,也可以根據實際業務情況動態地擴展集群中節點,
  • 高可用性: 佇列可以在集群中的機器上設定鏡像,使得在部分節點出現問題的情況下佇列仍然可用,
  • 支持多種協議: RabbitMQ 除了原生支持 AMQP 協議,還支持 STOMP、MQTT 等多種訊息中間件協議,
  • 多語言客戶端: RabbitMQ幾乎支持所有常用語言,比如 Java、Python、Ruby、PHP、C#、JavaScript等,
  • 易用的管理界面: RabbitMQ提供了一個易用的用戶界面,使得用戶可以監控和管理訊息、集群中的節點等,在安裝 RabbitMQ 的時候會介紹到,安裝好 RabbitMQ 就自帶管理界面,
  • 插件機制: RabbitMQ 提供了許多插件,以實作從多方面進行擴展,當然也可以撰寫自己的插件,感覺這個有點類似 Dubbo 的 SPI機制,

RabbitMQ 整體上是一個生產者與消費者模型,主要負責接收、存盤和轉發訊息,可以把訊息傳遞的程序想象成:當你將一個包裹送到郵局,郵局會暫存并最終將郵件通過郵遞員送到收件人的手上,RabbitMQ就好比由郵局、郵箱和郵遞員組成的一個系統,從計算機術語層面來說,RabbitMQ 模型更像是一種交換機模型,

下面再來看看圖—— RabbitMQ 的整體模型架構,
圖1-RabbitMQ 的整體模型架構

1.1 Producer(生產者) 和 Consumer(消費者)

  • Producer(生產者) :生產訊息的一方(郵件投遞者)
  • Consumer(消費者) :消費訊息的一方(郵件收件人)

訊息一般由 2 部分組成:訊息頭(或者說是標簽 Label)和 訊息體,訊息體也可以稱為 payLoad ,訊息體是不透明的,而訊息頭則由一系列的可選屬性組成,這些屬性包括 routing-key(路由鍵)、priority(相對于其他訊息的優先權)、delivery-mode(指出該訊息可能需要持久性存盤)等,生產者把訊息交由 RabbitMQ 后,RabbitMQ 會根據訊息頭把訊息發送給感興趣的 Consumer(消費者),

1.2 Exchange(交換器)

在 RabbitMQ 中,訊息并不是直接被投遞到 Queue(訊息佇列) 中的,中間還必須經過 Exchange(交換器) 這一層,Exchange(交換器) 會把我們的訊息分配到對應的 Queue(訊息佇列) 中,

Exchange(交換器) 用來接收生產者發送的訊息并將這些訊息路由給服務器中的佇列中,如果路由不到,或許會回傳給 Producer(生產者) ,或許會被直接丟棄掉 ,這里可以將RabbitMQ中的交換器看作一個簡單的物體,

RabbitMQ 的 Exchange(交換器) 有4種型別,不同的型別對應著不同的路由策略direct(默認)fanout, topic, 和 headers,不同型別的Exchange轉發訊息的策略有所區別,這個會在介紹 Exchange Types(交換器型別) 的時候介紹到,

Exchange(交換器) 示意圖如下:
Exchange(交換器) 示意圖
生產者將訊息發給交換器的時候,一般會指定一個 RoutingKey(路由鍵),用來指定這個訊息的路由規則,而這個 RoutingKey 需要與交換器型別和系結鍵(BindingKey)聯合使用才能最終生效

RabbitMQ 中通過 Binding(系結)Exchange(交換器)Queue(訊息佇列) 關聯起來,在系結的時候一般會指定一個 BindingKey(系結建) ,這樣 RabbitMQ 就知道如何正確將訊息路由到佇列了,如下圖所示,一個系結就是基于路由鍵將交換器和訊息佇列連接起來的路由規則,所以可以將交換器理解成一個由系結構成的路由表,Exchange 和 Queue 的系結可以是多對多的關系,

Binding(系結) 示意圖:
Binding(系結) 示意圖
生產者將訊息發送給交換器時,需要一個RoutingKey,當 BindingKey 和 RoutingKey 相匹配時,訊息會被路由到對應的佇列中,在系結多個佇列到同一個交換器的時候,這些系結允許使用相同的 BindingKey,BindingKey 并不是在所有的情況下都生效,它依賴于交換器型別,比如fanout型別的交換器就會無視,而是將訊息路由到所有系結到該交換器的佇列中,

1.3 Queue(訊息佇列)

Queue(訊息佇列) 用來保存訊息直到發送給消費者,它是訊息的容器,也是訊息的終點,一個訊息可投入一個或多個佇列,訊息一直在佇列里面,等待消費者連接到這個佇列將其取走,

RabbitMQ 中訊息只能存盤在 佇列 中,這一點和 Kafka 這種訊息中間件相反,Kafka 將訊息存盤在 topic(主題) 這個邏輯層面,而相對應的佇列邏輯只是topic實際存盤檔案中的位移標識, RabbitMQ 的生產者生產訊息并最終投遞到佇列中,消費者可以從佇列中獲取訊息并消費,

多個消費者可以訂閱同一個佇列,這時佇列中的訊息會被平均分攤(Round-Robin,即輪詢)給多個消費者進行處理,而不是每個消費者都收到所有的訊息并處理,這樣避免的訊息被重復消費,

RabbitMQ 不支持佇列層面的廣播消費,如果有廣播消費的需求,需要在其上進行二次開發,這樣會很麻煩,不建議這樣做,

1.4 Broker(訊息中間件的服務節點)

對于 RabbitMQ 來說,一個 RabbitMQ Broker 可以簡單地看作一個 RabbitMQ 服務節點,或者RabbitMQ服務實體,大多數情況下也可以將一個 RabbitMQ Broker 看作一臺 RabbitMQ 服務器,

下圖展示了生產者將訊息存入 RabbitMQ Broker,以及消費者從Broker中消費資料的整個流程,
訊息佇列的運轉程序
這樣圖1中的一些關于 RabbitMQ 的基本概念我們就介紹完畢了,下面再來介紹一下 Exchange Types(交換器型別)

1.5 Exchange Types(交換器型別)

RabbitMQ 常用的 Exchange Type 有 fanoutdirecttopicheaders 這四種(AMQP規范里還提到兩種 Exchange Type,分別為 system 與 自定義,這里不予以描述),

① fanout

fanout 型別的Exchange路由規則非常簡單,它會把所有發送到該Exchange的訊息路由到所有與它系結的Queue中,不需要做任何判斷操作,所以 fanout 型別是所有的交換機型別里面速度最快的,fanout 型別常用來廣播訊息,

② direct

direct 型別的Exchange路由規則也很簡單,它會把訊息路由到那些 Bindingkey 與 RoutingKey 完全匹配的 Queue 中,
direct 型別交換器
以上圖為例,如果發送訊息的時候設定路由鍵為“warning”,那么訊息會路由到 Queue1 和 Queue2,如果在發送訊息的時候設定路由鍵為"Info”或者"debug”,訊息只會路由到Queue2,如果以其他的路由鍵發送訊息,則訊息不會路由到這兩個佇列中,
direct 型別常用在處理有優先級的任務,根據任務的優先級把訊息發送到對應的佇列,這樣可以指派更多的資源去處理高優先級的佇列,

③ topic

前面講到direct型別的交換器路由規則是完全匹配 BindingKey 和 RoutingKey ,但是這種嚴格的匹配方式在很多情況下不能滿足實際業務的需求,topic型別的交換器在匹配規則上進行了擴展,它與 direct 型別的交換器相似,也是將訊息路由到 BindingKey 和 RoutingKey 相匹配的佇列中,但這里的匹配規則有些不同,它約定:

  • RoutingKey 為一個點號“.”分隔的字串(被點號“.”分隔開的每一段獨立的字串稱為一個單詞),如 “com.rabbitmq.client”、“java.util.concurrent”、“com.hidden.client”;
  • BindingKey 和 RoutingKey 一樣也是點號“.”分隔的字串;
  • BindingKey 中可以存在兩種特殊字串“*”和“#”,用于做模糊匹配,其中“*”用于匹配一個單詞,“#”用于匹配多個單詞(可以是零個),
    topic 型別交換器
    以上圖為例:
  • 路由鍵為 “com.rabbitmq.client” 的訊息會同時路由到 Queuel 和 Queue2;
  • 路由鍵為 “com.hidden.client” 的訊息只會路由到 Queue2 中;
  • 路由鍵為 “com.hidden.demo” 的訊息只會路由到 Queue2 中;
  • 路由鍵為 “java.rabbitmq.demo” 的訊息只會路由到Queuel中;
  • 路由鍵為 “java.util.concurrent” 的訊息將會被丟棄或者回傳給生產者(需要設定 mandatory 引數),因為它沒有匹配任何路由鍵,
④ headers(不推薦)

headers 型別的交換器不依賴于路由鍵的匹配規則來路由訊息,而是根據發送的訊息內容中的 headers 屬性進行匹配,在系結佇列和交換器時制定一組鍵值對,當發送訊息到交換器時,RabbitMQ會獲取到該訊息的 headers(也是一個鍵值對的形式)'對比其中的鍵值對是否完全匹配佇列和交換器系結時指定的鍵值對,如果完全匹配則訊息會路由到該佇列,否則不會路由到該佇列,headers 型別的交換器性能會很差,而且也不實用,基本上不會看到它的存在,

2.總結

用大白話說,RabbitMQ整個架構就是:客戶端、交換機、佇列,這三個角色因為交換機不同的模式(直連交換機、扇形交換機、主體交換機、首部交換機)以及不同的組裝形成了RabbitMQ使用的各種模式:簡單模式()、作業佇列模式、發布/訂閱模式、路由模式、通配符模式等,其最核心的莫過于佇列,提供者及對應入隊,消費后對應出隊,

3.Windows本地環境安裝RabbitMQ

3.1 下載Erlang

RabbitMQ是基于Erlang環境開發的,先下載個Erlang(24),https://erlang.org/download/otp_win64_24.0.exe,下載直接一鍵點安裝

3.2 安裝RabbitMQ(3.9.5)

https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.5/rabbitmq-server-3.9.5.exe,·1下載直接一鍵點安裝

3.3啟動

這個應該不用我說按啥啟動了吧

在這里插入圖片描述

啟動成功,如下

在這里插入圖片描述

3.4安裝管理插件

右鍵快捷方式打開檔案夾所在目錄
在這里插入圖片描述
執行:
rabbitmq-plugins enable rabbitmq_management

5.訪問后臺

后臺管理網址:
http://localhost:15672/
安裝后的默認初始
賬號:guest
密碼:guset
然后就得到了黑化版的RabbitMQ?
在這里插入圖片描述

4.從一個簡單的例子認識RabbitMQ

1.示例

依賴:

		 <dependency>
	        <groupId>org.springframework.boot</groupId>
			 <artifactId>spring-boot-starter-amqp</artifactId>
	        <version>2.4.1</version>
	    </dependency>

生產者:

package boot.spring.test;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @description:
 * @author:lx
 * @date: 2021/09/04 下午 3:12
 * @Copyright: lx
 */
public class Provider {

	/**
	 * 宣告的佇列名
	 */
	private final static String QUEUE_NAME = "test_queue";

	public static void main(String[] args) throws IOException, TimeoutException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("127.0.0.1");
		// 默認埠號
		connectionFactory.setPort(5672);
		connectionFactory.setUsername("guest");
		connectionFactory.setPassword("guest");
		connectionFactory.setVirtualHost("/");

		// 獲取TCP長連接
		Connection conn = connectionFactory.newConnection();

		// 創建通信“通道”,相當于TCP中的虛擬連接
		Channel channel = conn.createChannel();
		// 開啟RabbitMQ事務,當沒有接收到MQ反饋時拋出例外并回滾
		channel.txSelect();

		// 創建佇列,宣告并創建一個佇列,如果佇列已存在,則使用這個佇列
		// 第一個引數:佇列名稱
		// 第二個引數:是否持久化,false對應不持久化資料,MQ停掉資料就會丟失
		// 第三個引數:是否佇列私有化,false則代表所有消費者都可以訪問,true代表只有一次則擁有它的消費者才能一直使用,其它消費者不讓訪問
		// 第四個引數:是否自動洗掉,false代表連接停掉后不自動洗掉這個佇列
		// 其它額外引數:null
		channel.queueDeclare(QUEUE_NAME, true, false, false, null);
		String message = "hello world!";

		try {
			// 第一個引數:交換機,這里時簡單demo版本,沒有用到交換機
			// 第二個引數:佇列名稱
			// 第三個引數:額外的設定屬性
			// 第四個引數:要傳遞的訊息位元組陣列
			channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
		} catch (Exception e) {
			// 發生例外的回滾
			channel.txRollback();
		}

		// 正常流程提交事務
		channel.txCommit();
		channel.close();
		conn.close();
		System.out.println("發送成功!");
	}
}

消費者:

package boot.spring.test;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @description:
 * @author:lx
 * @date: 2021/09/04 下午 3:33
 * @Copyright: lx
 */
public class Consumer {

	private final static String QUEUE_NAME = "test_queue";

	public static void main(String[] args) throws IOException, TimeoutException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("127.0.0.1");
		connectionFactory.setPort(5672);
		connectionFactory.setUsername("guest");
		connectionFactory.setPassword("guest");
		connectionFactory.setVirtualHost("/");

		// 獲取TCP長連接
		Connection conn = connectionFactory.newConnection();

		// 創建通信“通道”,相當于TCP中的虛擬連接
		Channel channel = conn.createChannel();

		// 創建佇列,宣告并創建一個佇列,如果佇列已存在,則使用這個佇列
		// 第一個引數:佇列名稱
		// 第二個引數:是否持久化,false對應不持久化資料,MQ停掉資料就會丟失
		// 第三個引數:是否佇列私有化,false則代表所有消費者都可以訪問,true代表只有一次則擁有它的消費者才能一直使用,其它消費者不讓訪問
		// 第四個引數:是否自動洗掉,false代表連接停掉后不自動洗掉這個佇列
		// 其它額外引數:null
		channel.queueDeclare(QUEUE_NAME, true, false, false, null);

		// 創建一個訊息消費者
		// 第一個引數:佇列名稱
		// 第二個引數:第二個引數表示是否自動確認收到訊息,false代表手動編程確認訊息
		// 第三個引數:傳入DefaultConsumer的實作類
		channel.basicConsume(QUEUE_NAME, false, new Receiver(channel));

	}
}

/**
 * @description:
 * @author:lx
 * @date: 2021/09/04 下午 3:37
 * @Copyright: lx
 */
class Receiver extends DefaultConsumer {

	private Channel channel;

	/**
	 * 重寫建構式,channel通道物件需要從外層傳入,在handleDelivery中要用到
	 *
	 * @param channel
	 */
	public Receiver(Channel channel) {
		super(channel);
		this.channel = channel;
	}

	@Override
	public void handleDelivery(String consumerTag,
	                           Envelope envelope,
	                           AMQP.BasicProperties properties,
	                           byte[] body)
			throws IOException {
		String message = new String(body);
		System.out.println("消費者接收到的訊息:" + message);
		System.out.println("訊息的TagID:" + envelope.getDeliveryTag());
//		int i = 1 / 0;
		// false只簽收當前的訊息,設定為true的時候代表簽收該消費者所有未簽收的訊息
		channel.basicAck(envelope.getDeliveryTag(), false);
	}
}

2.重復消費

啟動生產者,來到管理頁面,可以看到訊息已經入隊,進入準備被消費的狀態,
在這里插入圖片描述
Debug啟動消費者后,在管理頁面可以看到,隊內訊息狀態由準備-轉變到了待回應狀態,total總數還是存在的,此時訊息已被接收到,但未被回應,
在這里插入圖片描述
由于斷點導致MQ超時未收到回應,狀態回滾到ready,訊息仍然在隊中,但事實上消費者已經消費過一次了,這里引出一個問題-重復消費,
在這里插入圖片描述
還是很多場景導致你發生例外回滾的情況還有很多,比如:
程式發送例外導致,順帶一提,程式例外會導致消費者程式崩潰,MQ也會一直阻塞在等待回應的階段
消費者行程突然GG
在這里插入圖片描述
使用代理將捕獲轉發,模擬丟包的情況

解決方案

既然重復消費這種情況是難以避免的,那么我們如何去處理這種情況呢?
消費端處理訊息的業務邏輯保持冪等性,
冪等性,通俗點說,就一個資料,或者一個請求,給你重復來多次,你得確保對應的資料是不會改變的,不能出錯,

1.你拿到這個訊息做資料庫的insert操作,那就容易了,給這個訊息做一個唯一主鍵,那么就算出現重復消費的情況,就會導致主鍵沖突,避免資料庫出現臟資料,
2.你拿到這個訊息做redis的set的操作,那就容易了,不用解決,因為你無論set幾次結果都是一樣的,set操作本來就算冪等操作,
3.準備一個第三方介質,來做消費記錄,以redis為例,給訊息分配一個全域id,只要消費過該訊息,將<id,message>以K-V形式寫入redis,那消費者開始消費前,先去redis中查詢有沒消費記錄即可,

3.訊息丟失

訊息在網路傳輸中丟失,MQ宕機丟失訊息

4.訊息積壓

程式例外會導致消費者程式崩潰,MQ也會一直阻塞在等待回應的階段,導致訊息一直堆積

5.MQ高可用

https://blog.csdn.net/yygEwing/article/details/116329666?utm_source=app&app_version=4.14.1

六、原始碼分析

從簡單的原始碼分析更深入的認知RabbitMQ
在這里插入圖片描述

Broker: 接收和分發訊息的應用,RabbitMQ Server就是Message Broker
Virtual Host: 處于多租戶和安全因素設計的,把AMQP的基本組件劃分到一個虛擬的分組中,類似于網路中的namespace概念,當多個不同的用戶使用同一個RabbitMQserver提供的服務時,可以劃分出多個vhost,每個用戶在自己的vhost創建exchange/queue等
Connection: publisher/consumer和broker之間的TCP連接
Channel: 如何每一次訪問RabbitMQ都建立一個Connection,在訊息量大的時候建立TCP Connection的開銷將是巨大的,效率也低,channel是在connection內部建立的邏輯連接,如果應用程式支持多執行緒,通常每個thread創建單獨的channel進行通訊,AMQPmethod包含了channelId幫助客戶端和message broker識別channel,所以channel之間是完全隔離的,Channel作為輕量級的Connection極大減少了作業系統建立TCP connection的開銷,

1.回顧設計模式

1.1 工廠方法模式

將多段代碼的共性行為抽象到介面中去定義,具體的實作由子類實作父類后去定義,最后,通過一個工廠類去根據傳參來選擇回傳對應的實體化物件,
關鍵詞:工廠類一般帶有Factory

1.2 抽象工廠模式

抽象工廠的本質是其它工廠類的抽象類,也就是將其他工廠類中的共性行為提取到了抽象工廠類
AbstractXXX

1.3 建造者模式

日常生活中,裝修房子會根據不同的場景、品牌、型號、價格等等組合形成了各式各樣的裝修風格(套餐A:現代簡約,套餐B:輕奢田園,套餐C:歐式豪華)

一些基本物料不會變,而其組合經常變化的時候,就可以選擇這樣的構建者模式來構建代碼,
Builder

2.理解RabbitMQ與客戶端的資料互動

3.帶著問題去看代碼

3.1 訊息是如何入隊的?

3.2 訊息是如何被消費的?

3.3 客戶端是如何建立連接的?

3.4 channel是什么?

3.5 RabbitMQ是如何實作異步的?

3.6 RabbitMQ如何確保訊息不會丟失?Ack

3.7 為什么消費者在啟動后會自動消費佇列中的訊息?

3.8 消費者接收到消費資訊,停止運行消費者后,會繼續執行消費行為?

4.核心思想

RabbitMQ實作MQ的核心思想是?其特點是?其中用到了什么設計模式?最有印象的是?

在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298080.html

標籤:其他

上一篇:【elasticsearch系列】windows安裝IK分詞器插件

下一篇:2020年技能樹

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more