小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

RabbitMQ 入門教程(四)

 夜貓速讀 2022-05-05 發(fā)布于湖北

RabbitMQ 中TTL消息介紹

1. 前言

Hello,大家好。本小節(jié)會(huì)為同學(xué)們介紹 RabbitMQ 中自帶的另一種機(jī)制,就是 TTL 消息,以及 TTL 消息隊(duì)列。TTL 消息和 TTL 消息隊(duì)列是我們實(shí)際工作中使用頻率較高的一種機(jī)制,這種機(jī)制規(guī)定了在特定條件下,消息的有效時(shí)間,通過應(yīng)用這種機(jī)制,我們可以很靈活地對消息進(jìn)行控制。

TTL 消息以及 TTL 消息隊(duì)列這種機(jī)制,一般不會(huì)單獨(dú)使用,在實(shí)際工作中都會(huì)搭配死信隊(duì)列一并使用,那么在本節(jié)中,會(huì)首先為同學(xué)們介紹何為 TTL 消息以及 TTL 消息隊(duì)列,在下一節(jié)就會(huì)為同學(xué)們介紹什么是死信隊(duì)列了。

話不多說,就讓我們先來了解一下什么是 TTL 消息吧。

本節(jié)主要內(nèi)容:

  • TTL 消息概述;

2. TTL 消息概述

基礎(chǔ)概念:

TTL,全稱為 Time to Live ,即生存時(shí)間。 說到這個(gè) TTL ,想必大家都有所接觸,這個(gè) TTL 并不是 RabbitMQ 中獨(dú)有的特性,我們在進(jìn)行應(yīng)用程序開發(fā)時(shí),我們使用的其他工具中,也具備這個(gè)生存時(shí)間的概念,只不過描述的可能不一樣,但是含義相同。那么在 RabbitMQ 中,TTL 描述的又是什么呢?

在 RabbitMQ 中,TTL 這一概念是作用于消息和消息隊(duì)列上,即為消息以及消息隊(duì)列規(guī)定了一個(gè)生存時(shí)間,當(dāng)消息或消息隊(duì)列的生存時(shí)間超過了 TTL 所規(guī)定的生存時(shí)間之后,消息就會(huì)失效,且不會(huì)被消費(fèi)。

其中,對于消息來說,一旦消息的生存時(shí)間超過了 TTL 所規(guī)定的消息生存時(shí)間,那么,這條消息會(huì)立即失效,并且不會(huì)被任何消費(fèi)者消費(fèi),且會(huì)變成一種死信,并最終會(huì)被 RabbitMQ 放入死信隊(duì)列中(相關(guān)概念下節(jié)介紹,下同)。

而對于消息隊(duì)列來說,如果消息隊(duì)列的生存時(shí)間超過了 TTL 所規(guī)定的消息隊(duì)列的生存時(shí)間,那么消息隊(duì)列會(huì)立即失效,且該消息隊(duì)列中的消息也會(huì)隨著消息隊(duì)列的失效而失效。 這就提醒我們,在對應(yīng)用程序中的消息進(jìn)行操作時(shí),可以根據(jù)業(yè)務(wù)需要來設(shè)置專門一條消息的生存時(shí)間,也可以設(shè)置同一消息類型的消息隊(duì)列的生存時(shí)間,以靈活控制消息的有效期限。

從消費(fèi)者的角度來說,我們也可以這樣理解:在消息被設(shè)置了 TTL 之后,如果這個(gè)消息的等待時(shí)間超過了 TTL ,則這個(gè)消息就不會(huì)被任何消費(fèi)者消費(fèi);從生產(chǎn)者的角度來說,生產(chǎn)者發(fā)送了一條消息到 RabbitMQ Server 中,且已經(jīng)設(shè)置了 TTL ,如果這個(gè)消息的等待時(shí)間超過了 TTL ,即使有消費(fèi)者來接收消息,這個(gè)消息也不會(huì)被接收,同時(shí),生產(chǎn)者也不會(huì)再次發(fā)送相同的消息。

在了解了 TTL 的基礎(chǔ)概念之后,我們還需要了解如何通過代碼,來配置 TTL 消息。

代碼實(shí)現(xiàn):

配置 TTL ,需要我們在生產(chǎn)端進(jìn)行配置,代碼如下:

ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("xx");
connectionFactory.setPort("5672");
connectionFactory.setVirtualHost("/");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChanel();
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
        .deliveryMode(2)
        .expiration("10000")
        .contentEncoding("UTF-8")
        .build();
channel.basicPublish(exchangeName, routingKey, true, properties, msg.getBytes());

代碼解釋:

第 1-5 行,我們使用 ConnectionFactory 創(chuàng)建了一個(gè)客戶端連接 RabbitMQ Server 的連接。

第 6 行,我們使用建立好的連接,來創(chuàng)建了一個(gè)頻道 channel 。

第 7-12 行,我們使用 AMQP.BasicProperties 來初始化了一個(gè)具體消息的 properties 參數(shù),初始化 properties 的過程采用了 AMQP 的調(diào)用鏈模式,即通過 AMQP.BasicProperties.Builder() 來對 properties 進(jìn)行初始化。

其中,deliveryMode 表示 properties 的投遞模式,2 表示持久化投遞,即 RabbitMQ Server 重啟之后依然有效;contentEncoding 表示 properties 的編碼模式,這里是支持中文的 UTF-8 格式;expiration 屬性就是來對當(dāng)前的消息設(shè)置生存時(shí)間的屬性,其單位為毫秒,這里設(shè)置的 TTL 為 10 秒, 當(dāng)我們對 properties 的屬性設(shè)置完畢后,調(diào)用 build 方法即可完成 properties 的構(gòu)建。

第 13 行,我們使用 channel 的 basicPublish 方法,將消息發(fā)送到 RabbitMQ Server 中,這里我們直接來看 basicPublish 方法的第四個(gè)參數(shù),其他參數(shù)已經(jīng)介紹很多次了,這里不再介紹。

我們都知道,在 RabbitMQ 中,一條具體的消息被分為了消息體和消息參數(shù)兩個(gè)部分, 其中,消息體指的是我們應(yīng)用程序中的數(shù)據(jù),消息參數(shù)指的是針對這一應(yīng)用程序中的數(shù)據(jù)進(jìn)行配置的一系列參數(shù),常見的參數(shù)有字符集、請求頭、投遞方式等。basicPublish 方法的第三個(gè)參數(shù)指的就是一條消息的消息參數(shù),即我們通過調(diào)用鏈模式來構(gòu)造出的 properties 參數(shù)。

將我們構(gòu)造好的 properties 參數(shù)一同發(fā)送到 RabbitMQ Server 中,那么,我們配置的 properties 的屬性就會(huì)生效,即該條消息的 TTL 為 10 秒。

上述代碼是配置 TTL 消息的,那么 TTL 消息隊(duì)列又該如何配置呢,我們看以下代碼:

代碼實(shí)現(xiàn):

// 省略客戶端連接 RabbitMQ Server 代碼
Map<String, Object> queueArgumentMap = new HashMap<>();
queueArgumentMap.put("x-message-ttl", "10000");
channel.queueDeclare(queueName, true, true, false, queueArgumentMap);
代碼塊1234

代碼解釋:

第 2-3 行,我們聲明了一個(gè)名為 queueArgumentMap 的 HashMap ,并且指定 key 為 x-message-ttl ,value 為 10000 ,且都是字符串類型。

第 4 行,我們使用 channel 的 queueDeclare 方法,來聲明一個(gè)隊(duì)列,這里我們重點(diǎn)看 queueDeclare 方法的第五個(gè)參數(shù),這個(gè)參數(shù)是一個(gè) Map 類型的 arguments 參數(shù),是專門來對隊(duì)列進(jìn)行額外配置的參數(shù), 其值就是我們聲明的這個(gè) queueArgumentMap 。

在 queueArgumentMap 中,key 為 RabbitMQ 官方規(guī)定的設(shè)置 TTL 的 key 值,value 即為我們要設(shè)置的 TTL 的具體時(shí)間,單位為毫秒,這里同樣設(shè)置為了 10 秒。

Tips: 1.在實(shí)際工作中,給消息或者消息隊(duì)列設(shè)置 TTL 是很常見的,所以需要同學(xué)們完全掌握本節(jié)內(nèi)容,這樣才能在工作中運(yùn)用自如;\2. queueArgumentMap 中 key 的指定必須要按照 RabbitMQ 官方給出的 key 值來聲明,不能自定義聲明,否則,將不會(huì)起到任何作用;\3. 在為消息或消息隊(duì)列設(shè)置了 TTL 之后,如果我們想要看到直觀地結(jié)果,我們可以自行編寫一個(gè)測試程序,并結(jié)合 RabbitMQ 的消息管控臺(tái)來觀察,這樣效果會(huì)很明顯。

3. 小結(jié)

本小節(jié)為同學(xué)們介紹了 RabbitMQ 中,如何為消息以及消息隊(duì)列設(shè)置 TTL 生存時(shí)間。從 TTL 的基礎(chǔ)概念開始,到 TTL 消息以及 TTL 消息隊(duì)列的編碼實(shí)現(xiàn)結(jié)束,詳細(xì)介紹了 TTL 是什么、TTL 的作用,以及不同組件下如何配置 TTL ,TTL 在實(shí)際工作中應(yīng)用較多,希望同學(xué)們可以完全掌握通過代碼的方式來對消息和消息隊(duì)列配置 TTL ,這樣我們才能對消息更加靈活地進(jìn)行配置。

RabbitMQ 死信隊(duì)列基礎(chǔ)概念與配置概述

1. 前言

Hello,大家好。本小節(jié)會(huì)為同學(xué)們介紹 RabbitMQ 中的死信隊(duì)列及其基礎(chǔ)配置。死信隊(duì)列作為 RabbitMQ 中最后一個(gè)特性,其在實(shí)際工作中發(fā)揮著重要的作用。本節(jié)會(huì)從死信隊(duì)列的前置概念開始,到死信隊(duì)列的基礎(chǔ)概念,最后介紹死信隊(duì)列的基本使用方法和基本配置結(jié)束,詳細(xì)介紹死信隊(duì)列的基礎(chǔ)概念和基本使用方法。

話不多說,讓我們直入正題吧。

本節(jié)主要內(nèi)容:

  • 死信隊(duì)列前置概念概述;

  • 死信隊(duì)列基礎(chǔ)概念概述;

  • 死信隊(duì)列基本使用概述;

2. 死信隊(duì)列前置概念概述

在正式介紹死信隊(duì)列的基礎(chǔ)概念之前,需要同學(xué)們先了解一些死信隊(duì)列的前置概念,這些前置概念是后續(xù)理解死信隊(duì)列的基礎(chǔ),同學(xué)們只有對這些前置概念有一個(gè)理解之后,才能很好地理解什么是死信隊(duì)列。

什么是隊(duì)列:

隊(duì)列并不是只存在于 RabbitMQ 中,隊(duì)列是一種計(jì)算機(jī)領(lǐng)域中的基本數(shù)據(jù)結(jié)構(gòu),其描述了數(shù)據(jù)在計(jì)算機(jī)內(nèi)存中垂直分布的特點(diǎn)。 我們可以把隊(duì)列看做是我們?nèi)粘I钪信抨?duì)做核酸的場景:當(dāng)有一個(gè)人去做的時(shí)候,這個(gè)時(shí)候沒有隊(duì)伍,直接做就行了;當(dāng)有十個(gè)人去做的時(shí)候,這個(gè)時(shí)候就需要排隊(duì)了,而排隊(duì)的這個(gè)過程就是隊(duì)列形成的過程。

當(dāng)再有人需要去做的時(shí)候,這個(gè)人只能排在隊(duì)尾,不能夠插隊(duì),而隊(duì)前的人由于比隊(duì)尾的人先到,所以隊(duì)前的人就比隊(duì)尾的人先做核酸,以此反復(fù)這個(gè)過程,直到所有人都做完核酸為止。

而隊(duì)列描述的就是這樣的場景,在上述例子中,形成隊(duì)伍的過程就是我們的應(yīng)用數(shù)據(jù)入隊(duì)的過程,先入隊(duì)的數(shù)據(jù)可以先被處理,而后入隊(duì)的數(shù)據(jù)只能等待前入隊(duì)的數(shù)據(jù)處理完畢之后才能進(jìn)行處理,這就是隊(duì)列先入先出的特點(diǎn)。

假設(shè)我們有 6 條數(shù)據(jù)需要入隊(duì),以下是數(shù)據(jù)入隊(duì)過程:

1 號數(shù)據(jù)會(huì)先入隊(duì),然后排在 1 好數(shù)據(jù)后面的 2 3 4 5 6 好數(shù)據(jù)會(huì)依次入隊(duì),入隊(duì)完成后的隊(duì)列如下圖所示:

說白了,隊(duì)列就是數(shù)據(jù)按照固定的排列方式在計(jì)算機(jī)中存儲(chǔ)的一種表現(xiàn)形式,而隊(duì)列中的數(shù)據(jù)處理原則就是先入隊(duì)的數(shù)據(jù)先進(jìn)行處理,后入隊(duì)的數(shù)據(jù)后進(jìn)行處理。RabbitMQ 中的隊(duì)列也是一樣的,只不過這些隊(duì)列里面存儲(chǔ)的都是被稱為消息的數(shù)據(jù),所以這些隊(duì)列被稱為消息隊(duì)列, 即在 RabbitMQ 中,根據(jù)消息類型的不同,會(huì)形成很多不同類型的隊(duì)列,但是這些隊(duì)列歸根到底,其本質(zhì)依然是消息隊(duì)列。

什么是死信:

我們知道,在 RabbitMQ 中充當(dāng)主角的就是消息,在不同場景下,消息會(huì)有不同地表現(xiàn)。死信就是消息在特定場景下的一種表現(xiàn)形式,這些場景包括:消息被拒絕訪問,即 RabbitMQ Server 返回 nack 的信號時(shí)、消息的 TTL 過期時(shí)、消息隊(duì)列達(dá)到最大長度,消息不能入隊(duì)時(shí)。

經(jīng)常產(chǎn)生死信的場景就是上述三種場景,即消息在這三種場景中時(shí),被稱為死信。

3. 死信隊(duì)列基礎(chǔ)概念概述

通過前置概念的介紹,我們知道了死信的基礎(chǔ)的概念,那么死信隊(duì)列又是什么呢?

結(jié)合上述對隊(duì)列基礎(chǔ)概念的介紹,我們不難得出:死信隊(duì)列就是用于儲(chǔ)存死信的消息隊(duì)列,在死信隊(duì)列中,有且只有死信構(gòu)成,不會(huì)存在其余類型的消息,這就是死信隊(duì)列。

死信隊(duì)列在 RabbitMQ 中并不會(huì)單獨(dú)存在,往往死信隊(duì)列都會(huì)綁定這一個(gè)普通的消息隊(duì)列,當(dāng)所綁定的消息隊(duì)列中,有消息變成死信了,那么這個(gè)消息就會(huì)重新被交換機(jī)路由到指定的死信隊(duì)列中去,我們可以通過對這個(gè)死信隊(duì)列進(jìn)行監(jiān)聽,從而手動(dòng)的去對這一消息進(jìn)行補(bǔ)償。

那么,我們到底如何來使用死信隊(duì)列呢?

4. 死信隊(duì)列基本使用概述

在 RabbitMQ 中,死信隊(duì)列的標(biāo)識為 x-dead-letter-exchange ,通過觀察死信隊(duì)列的標(biāo)識,我們不難發(fā)現(xiàn),其標(biāo)識最后為 exchange ,即 RabbitMQ 中的交換機(jī),沒錯(cuò),RabbitMQ 中的死信隊(duì)列就是由死信交換機(jī)而得出的。

要想使用死信隊(duì)列,我們需要首先聲明一個(gè)普通的消息隊(duì)列,并將死信隊(duì)列的標(biāo)識綁定到這個(gè)普通的消息隊(duì)列上, 這個(gè)過程需要我們在生產(chǎn)端進(jìn)行配置,代碼如下所示:

ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("xx");
connectionFactory.setPort("5672");
connectionFactory.setVirtualHost("/");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChanel();
Map<String, Object> argumentsMap = new HashMap();
argumentsMap.put("x-dead-letter-exchange", "dlx_exchange");
channel.exchangeDeclare("dlx_common_exchange", "direct", true, false, null);
channel.queueDeclare("dlx_common_queue", true, false, false, argumentsMap);
channel.queueBind("dlx_common_queue", "dlx_common_exchange", routingKey);

代碼解釋:

第 1-5 行,我們使用 ConnectionFactory 創(chuàng)建了一個(gè)客戶端連接 RabbitMQ Server 的連接。

第 6 行,我們使用建立好的連接,來創(chuàng)建了一個(gè)頻道 channel 。

第 7-8 行,我們聲明了一個(gè)普通隊(duì)列的額外參數(shù)的 Map ,這個(gè) Map 的 key 就是死信隊(duì)列的標(biāo)識,value 就是我們后續(xù)聲明的真正的死信交換機(jī)的名稱。

第 9-10 行,我們依次使用 channel 的 exchangeDeclare 方法和 queueDeclare 方法,分別聲明了一個(gè)名為 dlx_common_exchange 的交換機(jī)和名為 dlx_common_queue 的普通消息隊(duì)列,之所以名稱中有 common ,是因?yàn)橐獙@個(gè)交換機(jī)和隊(duì)列做一個(gè)標(biāo)識,表示該交換機(jī)和隊(duì)列是綁定了死信隊(duì)列的。

第 11 行,我們使用 channel 的 queueBind 方法來講聲明的普通交換機(jī)和消息隊(duì)列進(jìn)行綁定,并且制定了 routingKey ,這樣消息就可以經(jīng) dlx_common_exchange 根據(jù) routingKey 來路由到 dlx_common_queue 中。

在我們聲明了要綁定死信隊(duì)列的普通隊(duì)列之后,最后我們需要聲明真正的死信隊(duì)列,代碼如下所示:

// 省略客戶端連接 RabbitMQ Server 的過程
channel.exchangeDeclare("dlx_exchange", "direct", true, false, null);
channel.queueDeclare("dlx_queue", true, false, false, null);
channel.queueBind("dlx_queue", "dlx_exchange", routingKey);

代碼解釋:

第 1 行,我們使用 chanel 的 exchangeDeclare 方法來聲明了一個(gè)名為 dlx_exchange 的交換機(jī)。

第 2 行,我們使用 channel 的 queueDeclare 方法來聲明了一個(gè)名為 dlx_queue 的隊(duì)列。

第 3 行,我們使用 channel 的 queueBind 方法,來將 dlx_exchange 的交換機(jī)與 dlx_queue 隊(duì)列進(jìn)行了綁定。

當(dāng)我們完成上述過程之后,死信隊(duì)列就配置完成了,這也是死信隊(duì)列的基本使用方法。

Tips: 1. 從聲明死信隊(duì)列的代碼段中,我們不難看出,我們所聲明的交換機(jī)和隊(duì)列也都是普通的,只不過我們聲明的這個(gè)交換機(jī)和隊(duì)列是用來存儲(chǔ) dlx_common_queue 隊(duì)列中的死信的;\2. 死信隊(duì)列的使用在實(shí)際工作中非常重要,它可以幫助我們對那些異常的消息進(jìn)行監(jiān)控,并根據(jù)這些監(jiān)控信息制定相應(yīng)的消息補(bǔ)償策略,這點(diǎn)同學(xué)們注意;\3. 一定要注意在聲明普通隊(duì)列時(shí),我們聲明的名為 argumetsMap 的變量,這個(gè)是綁定死信隊(duì)列的關(guān)鍵。

5. 小結(jié)

本小節(jié)為同學(xué)們介紹了 RabbitMQ 中,死信隊(duì)列的前置概念、死信隊(duì)列的基礎(chǔ)概念,以及死信隊(duì)列的基本使用。我們只有在了解了死信隊(duì)列的前置概念之后,我們才能理解死信隊(duì)列的基礎(chǔ)概念,同時(shí),我們只有清楚的明白了應(yīng)用死信隊(duì)列的步驟,我們才能正確的用好死信隊(duì)列。

死信隊(duì)列在實(shí)際工作中使用頻率非常高,希望同學(xué)們可以清楚地理解本節(jié)中的基礎(chǔ)概念和代碼實(shí)現(xiàn),這些都是應(yīng)用死信隊(duì)列基礎(chǔ)中的基礎(chǔ),望同學(xué)們注意。

RabbitAdmin 基礎(chǔ)概念詳解與配置

1. 前言

Hello,大家好。本小節(jié)作為第三章-Spring 生態(tài)鏈與 RabbitMQ 整合的開篇,會(huì)為同學(xué)們介紹,在 Spring 生態(tài)鏈中,RabbitMQ 是如何與 Spring 進(jìn)行整合的,包括從最初的在 Spring 中初始化 RabbitMQ 、以及如何在 Spring 中使用 RabbitMQ 發(fā)送消息,以及后續(xù)在 Spring 中如何對消息進(jìn)行監(jiān)聽等基礎(chǔ)核心內(nèi)容。

本小節(jié)首先會(huì)為各位同學(xué)們介紹,如何在 Spring 中初始化 RabbitMQ 。包括初始化 RabbitMQ 所使用的 Spring 組件,以及該組件的基本使用方法,快速助力同學(xué)們將 RabbitMQ 與 Spring 進(jìn)行整合。

本節(jié)主要內(nèi)容:

  • RabbitAdmin 基礎(chǔ)概念概述;

  • RabbitAdmin 基礎(chǔ)配置概述。

2. RabbitAdmin 基礎(chǔ)概念概述

基礎(chǔ)概念:

在 Spring 中,我們首先會(huì)接觸到 RabbitAdmin 。我們都知道,RabbitMQ 是基于 AMQP 協(xié)議和 erlang 語言進(jìn)行編碼開發(fā)的,所以,在 Spring 中我們無法直接使用 RabbitMQ ,Spring 團(tuán)隊(duì)考慮到了這一點(diǎn),所以做了一種名為 Spring-AMQP 的中間層依賴,我們可以把這個(gè)依賴?yán)斫獬晌覀儜?yīng)用程序中的 Mapper 層,即數(shù)據(jù)庫與實(shí)體間的映射關(guān)系。

Spring-AMQP 中間層依賴規(guī)定了一種映射關(guān)系,這種映射關(guān)系可以直接把 RabbitMQ 中的各種元素與 Java 程序相對應(yīng),我們只需要通過像編寫普通 Java 程序那樣即可在 Spring 中使用 RabbitMQ 了。

RabbitAdmin 是 Spring-AMQP 中的核心基礎(chǔ)組件,是我們在 Spring 中對 RabbitMQ 進(jìn)行初始化的必須組件, 其提供了 RabbitMQ 中聲明交換機(jī)、聲明隊(duì)列、綁定交換機(jī)和隊(duì)列,以及綁定路由 Key 等其他 API ,RabbitAdmin 正式由此得名。

在介紹完 RabbitAdmin 基礎(chǔ)概念之后,下面讓我們來看一下如何對 RabbitAdmin 進(jìn)行配置吧。

3. RabbitAdmin 基礎(chǔ)配置概述

在對 RabbitAdmin 配置進(jìn)行介紹之前,我們需要先引入 RabbitAdmin 的依賴包。RabbitAdmin 的依賴包共有兩個(gè),接下來依次進(jìn)行介紹。

3.1 引入 RabbitAdmin

以 Maven 引入方式為例,引入代碼如下所示:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
代碼塊1234

上述依賴是 SpringBoot 的 Starter 中封裝好的 amqp 依賴,也是 Spring 與 RabbitMQ 進(jìn)行整合的基礎(chǔ)依賴。

<dependency>
  <groupId>com.rabbitmq</groupId>
  <artifactId>amqp-client</artifactId>
  <version>3.6.5</version>
</dependency>

上述依賴是 RabbitMQ 的客戶端依賴,即 amqp-client ,我們都知道 RabbitMQ 分為 Server 端和 Client 端,其中,Server 端正是我們所啟動(dòng)的 RabbitMQ Server 服務(wù),客戶端就是我們所有使用 RabbitMQ 的應(yīng)用程序。

本依賴正是 RabbitMQ 的 Client 端,如果我們想在應(yīng)用程序中使用 RabbitMQ ,那么這個(gè)依賴是必須的。

3.2 RabbitAdmin 基礎(chǔ)配置

在我們的應(yīng)用程序中引入相應(yīng)的 RabbitMQ 依賴之后,接下來我們需要在應(yīng)用程序中對 RabbitMQ 進(jìn)行初始化,而進(jìn)行初始化的 Spring 組件就是我們的 RabbitAdmin 。

初始化 RabbitMQ 客戶端連接

初始化 RabbitMQ 客戶端連接的代碼如下所示:

代碼實(shí)現(xiàn):

@Bean
public ConnectionFactory connectionFactory () {
  CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
  cachingConnectionFactory.setAddresses("82.156.65.57:5672");
  cachingConnectionFactory.setUsername("guest");
  cachingConnectionFactory.setPassword("guest");
  cachingConnectionFactory.setVirtualHost("/");
  return cachingConnectionFactory;
}

代碼解釋:

第 1 行,我們使用 Spring 的 Bean 注解將我們聲明的 connectionFactory 方法注入到 Spring 容器中。

第 2 行,我們使用 Spring-AMQP 中的 ConnectionFactory 類,來聲明了一個(gè)名為 connectionFactory 的連接工廠方法,用于對 RabbitMQ 進(jìn)行初始化。

第 3 行,我們實(shí)例化了一個(gè) cachingConnectionFactory 實(shí)例,該實(shí)例是 Spring-AMQP 中對 RabbitMQ 連接信息進(jìn)行初始化的基礎(chǔ)實(shí)例,所有的 RabbitMQ 連接信息均來源于該實(shí)例。

第 4-7 行,我們通過 cachingConnectionFactory 實(shí)例的 setAddresses 、setUsername 、setPassword 、setVirtualHost 方法來分別初始化 RabbitMQ Server 的服務(wù)地址、用戶名、密碼、虛擬主機(jī)。

第 8 行,我們將填充好的 cachingConnectionFactory 實(shí)例進(jìn)行返回,以初始化完成 RabbitMQ 客戶端連接。

通過上述代碼的配置,我們已經(jīng)初始化了 RabbitMQ 的客戶端連接,接下來我們需要繼續(xù)初始化 RabbitAdmin ,以在 Spring 中管理 RabbitMQ 。

初始化 RabbitAdmin 的方法如下代碼所示:

@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
   RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
   rabbitAdmin.setAutoStartup(true);
   return rabbitAdmin;
}

代碼解釋:

第 2 行,我們 RabbitAdmin 類來聲明了一個(gè)名為 rabbitAdmin 的方法,用來初始化 RabbitAdmin 。

第 4-6 行,我們首先根據(jù)上述的 connectionFactory 來實(shí)例化了一個(gè) RabbitAdmin 實(shí)例;然后通過 rabbitAdmin 實(shí)例的 setAutoStartup 方法置位 true 來設(shè)置 RabbitAdmin 的自動(dòng)啟動(dòng);最后,我們將設(shè)置好的 rabbitAdmin 實(shí)例進(jìn)行返回,以使用 RabbitAdmin 。

Tips: 1. @Bean 注解是 Spring 容器中自帶的注解,其作用就是將我們應(yīng)用程序中的類,或者方法來注入到 Spring 容器中,作為 Spring 配置的一部分。\2. 當(dāng)我們設(shè)置好了 connectionFactory 和 rabbitAdmin 組件之后,一旦啟動(dòng)我們的應(yīng)用程序,這兩個(gè)組件就會(huì)自動(dòng)進(jìn)行初始化。

RabbitAdmin 核心 API 介紹

下面我們來看一下在 RabbitAdmin 中,都有哪些核心的 API 。

declareExchange() 聲明交換機(jī)的方法;

declareQueue() 聲明隊(duì)列的方法;

declareBinding() 將交換機(jī)與隊(duì)列進(jìn)行綁定的方法;

purgeQueue() 清空指定隊(duì)列中所有的消息的方法。

在 RabbitAdmin 中,我們可以通過實(shí)例化對象的方法,來創(chuàng)建一個(gè)交換機(jī),或者一個(gè)隊(duì)列,像下面這樣:

new DirectExchange("test.direct", false, false)
new Queue("test.direct.queue", false)
代碼塊12

在上述 new DirectExchange 方法中,第一個(gè)參數(shù)表示交換機(jī)的名稱;第二個(gè)參數(shù)表示是否持久化;第三個(gè)參數(shù)表示是否自動(dòng)刪除。

在上述 new Queue 方法中,第一個(gè)參數(shù)表示隊(duì)列的名稱;第二個(gè)參數(shù)表示是否持久化。

Tips: 這兩個(gè)方法在 RabbitAdmin 中使用頻率很高,同學(xué)們注意。

那么,我們應(yīng)該如何使用 RabbitAdmin 這些核心的 API 呢,如下代碼所示:

@Autowired
private RabbitAdmin rabbitAdmin;
rabbitAdmin.declareExchange(new DirectExchange("test.direct", false, false));
rabbitAdmin.declareQueue(new Queue("test.direct.queue", false));
rabbitAdmin.declareBinding(new Binding("test.direct.queue", Binding.DestinationType.QUEUE,
                "test.direct", "direct", new HashMap<>()));

代碼解釋:

第 1-2 行,我們使用 Autowired 注解,來講 RabbitAdmin 注入進(jìn)來,并用一個(gè)私有變量 rabbitAdmin 來接收。

第 3 行,我們使用 declareExchange 方法來聲明了一個(gè)名為 test.direct 的交換機(jī)。

第 4 行,我們使用 declareQueue 方法來聲明了一個(gè)名為 test.direct.queue 的隊(duì)列。

第 5 行,我們使用 declareBinding 方法來將我們聲明的交換機(jī)和消息隊(duì)列進(jìn)行綁定,其中,test.direct.queue 為我們聲明的隊(duì)列;Binding.DestinationType.QUEUE 為綁定的類型;test.direct 為我們聲明的交換機(jī);direct 為我們要綁定的交換機(jī)的類型;new HashMap<>() 表示隊(duì)列的最后一個(gè) arguments 屬性,其屬性是 Map 類型,這里置為了空。

我們可以通過這些核心的 API 來聲明 RabbitMQ 中最基礎(chǔ)的元素,包括交換機(jī)、消息隊(duì)列、路由 Key ,以及綁定規(guī)則。

Tips: 1. Binding.DestinationType 這種類型,除了 QUEUE 隊(duì)列類型,還有一個(gè) EXCHANGE 類型,同學(xué)們可以課下進(jìn)行了解;\2. 了解 RabbitAdmin 的基礎(chǔ)概念和基礎(chǔ)配置,是 RabbitMQ 整合 Spring 基礎(chǔ)中的基礎(chǔ),同學(xué)們要了解每個(gè)基礎(chǔ)概念和核心 API 。

4. 小結(jié)

本小節(jié)為同學(xué)們介紹了在 Spring 生態(tài)中,如何集成 RabbitMQ 。從介紹 RabbitAdmin 基礎(chǔ)概念開始,到引入 RabbitAdmin 依賴,最后到 RabbitAdmin 基礎(chǔ)配置介紹結(jié)束,詳細(xì)介紹了如何在 Spring 中,初始化 RabbitMQ 、聲明交換機(jī)、聲明消息隊(duì)列,以及建立綁定關(guān)系等,旨在幫助同學(xué)們可以清楚地入門 RabbitAdmin ,我們只有在優(yōu)先掌握了 RabbitAdmin 之后,才可以在 Spring 中進(jìn)行后續(xù)操作,同學(xué)們加油。

RabbitTemplate 基礎(chǔ)概念詳解與配置

1. 前言

Hello,大家好。本小節(jié)會(huì)為同學(xué)們介紹 RabbitMQ 在 Spring 生態(tài)中的第二個(gè)核心組件,也就是 RabbitTemplate ,RabbitTemplate 作為 Spring 生態(tài)中的第二個(gè)核心組件,其在整個(gè) RabbitMQ 中也扮演著重要的角色。

本小節(jié)首先會(huì)為各位同學(xué)介紹,什么是 RabbitTemplate ,即 RabbitTemplate 的基礎(chǔ)概念,以及 RabbitTemplate 所發(fā)揮的作用,最后要給各位同學(xué)介紹 RabbitTemplate 的基本使用方法,即 RabbitTemplate 的基礎(chǔ)配置。RabbitTemplate 的基礎(chǔ)概念和基本使用都需我們同學(xué)有所了解和掌握。

本節(jié)主要內(nèi)容:

  • RabbitTemplate 基礎(chǔ)概念概述;

  • RabbitTemplate 基礎(chǔ)配置概述。

2. RabbitTemplate 基礎(chǔ)概念概述

基礎(chǔ)概念:

在上一節(jié)中,我們接觸了 RabbitMQ 在 Spring 生態(tài)中的第一個(gè)核心組件-RabbitAdmin ,了解了 RabbitAdmin 的基礎(chǔ)概念和基本使用方法,知道了如何使用 RabbitAdmin 來配置客戶端,也就是我們的應(yīng)用程序連接 RabbitMQ Server 的配置方法,其實(shí) RabbitAdmin 的主要目的就是與 RabbitMQ Server 建立連接,并聲明 RabbitMQ 的核心元素。

在對 RabbitAdmin 有所了解之后,我們只是與 RabbitMQ Server 建立了一個(gè)可用的連接,并根據(jù)需求聲明了 RabbitMQ 中的交換機(jī)、消息隊(duì)列,以及綁定關(guān)系,此時(shí),還并沒有向 RabbitMQ Server 發(fā)送任何消息,我們的應(yīng)用數(shù)據(jù)還不能被 RabbitMQ Server 處理,那么我們應(yīng)該怎樣在 Spring 中向 RabbitMQ Server 發(fā)送消息呢?

要想在 Spring 中向 RabbitMQ Server 發(fā)送消息,我們需要使用 RabbitTemplate 才行。 RabbitTemplate 是 Spring-AMQP 依賴為我們提供的一種 RabbitMQ 消息模板,它像 RabbitAdmin 一樣,與 RabbitMQ Server 建立了一種映射關(guān)系,我們只需要使用 Java 代碼來對 RabbitTemplate 進(jìn)行配置,就可以將我們應(yīng)用程序中的數(shù)據(jù)發(fā)送到 RabbitMQ Server 中。

RabbitTemplate 提供了編輯消息、發(fā)送消息、發(fā)送消息前的監(jiān)聽、發(fā)送消息后的監(jiān)聽等消息制造和消息監(jiān)聽功能,可以讓我們像操作原生 RabbitMQ API 那樣在 Spring 中通過 RabbitTemplate 來操作消息并發(fā)送和監(jiān)聽消息,這就是 RabbitTemplate 的作用之處。

我們可以通俗的來這樣理解 RabbitTemplate ,對于 RabbitAdmin 而言,RabbitAdmin 是將應(yīng)用程序和 RabbitMQ Server 建立鏈接的,而 RabbitTemplate 則是在建立連接之后,將我們應(yīng)用程序中的數(shù)據(jù)發(fā)送到 RabbitMQ Server 中的。

在介紹完 RabbitTemplate 基礎(chǔ)概念之后,下面讓我們來看一下如何對 RabbitTemplate 進(jìn)行配置吧。

3. RabbitTemplate 基礎(chǔ)配置概述

對 RabbitTemplate 進(jìn)行配置,和 RabbitAdmin 的配置步驟相似,都需要首先引入 Spring-AMQP 的依賴,就是我們上節(jié)中所述的如下兩個(gè)依賴:

3.1 引入 RabbitTemplate

以 Maven 引入方式為例,引入代碼如下所示:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
  <groupId>com.rabbitmq</groupId>
  <artifactId>amqp-client</artifactId>
  <version>3.6.5</version>
</dependency>

和 RabbitAdmin 相同,在將這兩個(gè)依賴進(jìn)行引入之后,我們就可以對 RabbitTemplate 進(jìn)行配置了。

3.2 RabbitTemplate 基礎(chǔ)配置

初始化 RabbitTemplate 消息模板

在使用 RabbitTemplate 消息模板來往 RabbitMQ Server 中發(fā)送消息之前,我們需要先對 RabbitTemplate 消息模板進(jìn)行初始化,這個(gè)初始化過程非常簡單,初始化 RabbitTemplate 消息模板的代碼如下所示:

代碼實(shí)現(xiàn):

@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
  RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
  return rabbitTemplate;
}

代碼解釋:

第 1 行,我們使用 Spring 的 Bean 注解將我們聲明的 rabbitTemplate 方法注入到 Spring 容器中,這樣 Spring 容器就可以監(jiān)聽到我們注入的配置。

第 2 行,我們使用 Spring-AMQP 中的 RabbitTemplate 類,來聲明了一個(gè)名為 rabbitTemplate 的方法,用來對 RabbitTemplate 消息模板進(jìn)行初始化。

第 3 行,我們實(shí)例化了一個(gè) rabbitTemplate 實(shí)例,該實(shí)例是 Spring-AMQP 中對 RabbitTemplate 消息模板進(jìn)行初始化的實(shí)例,要想使用 RabbitTemplate 發(fā)送消息,就必須要初始化該實(shí)例。

第 4 行,我們將初始化好的 rabbitTemplate 實(shí)例進(jìn)行返回。

Tips: 1. @Bean 注解是 Spring 容器中自帶的注解,其作用就是將我們應(yīng)用程序中的類,或者方法來注入到 Spring 容器中,作為 Spring 配置的一部分。\2. RabbitTemplate 實(shí)例接收我們所定義的 ConnectionFactory 連接,傳入的連接名稱應(yīng)該和我們定義的 connectionFactory 名稱保持一致,即與使用 Bean 注解來聲明的連接名稱保持一致,如果名稱不保持一致,則 RabbitTemplate 就不會(huì)初始化,且會(huì)拋出異常。

RabbitTemplate 核心 API 介紹

下面我們來看一下在 RabbitTemplate 中,都有哪些核心的 API 。

MessageProperties 實(shí)例,用于對消息的 properties 參數(shù)進(jìn)行描述;

Message 實(shí)例,用于對消息體進(jìn)行描述;

send() 方法,用于將原始消息發(fā)送到 RabbitMQ Server 中;

convertAndSend() 方法,用于將原始消息進(jìn)行轉(zhuǎn)換,并且將轉(zhuǎn)換過后的消息發(fā)送到 RabbitMQ Server 中;

addListener() 方法,用于為當(dāng)前消息模板設(shè)置消息監(jiān)聽類型。

在介紹完常用核心 API 之后,接下來我們用一個(gè)發(fā)送消息的例子,來詳細(xì)說明一下這下常用核心 API ,如下代碼所示:

@Autowired
private RabbitTemplate rabbitTemplate;
MessageProperties messageProperties = new MessageProperties();
messageProperties.getHeaders().put("test1", "test1");
messageProperties.getHeaders().put("test2", "test2");
Message message = new Message("Hello RabbitTemplate".getBytes(), messageProperties);
rabbitTemplate.convertAndSend("test_direct_001", "test.123", message, new MessagePostProcessor() {
  @Override
  public Message postProcessMessage(Message message) throws AmqpException {
  message.getMessageProperties().getHeaders().put("test1", "test111");
  message.getMessageProperties().getHeaders().put("test2", "test222");
  return message;
  }
});

代碼解釋:

第 1-2 行,我們使用 Autowired 注解,來將 RabbitTemplate 注入進(jìn)來,并用一個(gè)私有變量 rabbitTemplate 來接收。

第 3 行,我們實(shí)例化了一個(gè) MessageProperties 的實(shí)例 messageProperties 。

第 4-5 行,我們使用 messageProperties 實(shí)例的 getHeaders 方法獲取到消息的 headers 參數(shù),并分別 put 了兩個(gè)不同的 header 。

第 6 行,我們初始化了一個(gè) Message 消息實(shí)例 message ,并在構(gòu)造方法中設(shè)置了消息體的內(nèi)容為 Hello RabbitTemplate ,且將該消息的額外參數(shù) messageProperties 也一并進(jìn)行了設(shè)置。

第 7-14 行,我們使用 rabbitTemplate 的 convertAndSend 方法,將消息進(jìn)行轉(zhuǎn)換之后發(fā)送到了 RabbitMQ Server 中, 其中,convertAndSend 方法的第一個(gè)參數(shù)為要使用的交換機(jī)名稱,這里是 test_direct_001 ,第二個(gè)參數(shù)為 routingKey ,這里是 test.123 ,第三個(gè)參數(shù)是我們需要發(fā)送的消息 message ,第四個(gè)參數(shù)則是消息發(fā)送成功后的監(jiān)聽器。

對于這個(gè)監(jiān)聽器,這里采用了 new MessagePostProcessor 的匿名內(nèi)部類的形式進(jìn)行實(shí)現(xiàn),要添加 MessagePostProcessor 消息監(jiān)聽器,需要重寫 postProcessMessage 方法,即消息發(fā)送成功后的方法,在該方法中,我們可以對消息發(fā)送成功后進(jìn)行進(jìn)一步的設(shè)置,最后將設(shè)置好的 Message 進(jìn)行返回。

關(guān)于 send 方法和 addListener 方法,如下代碼所示:

rabbitTemplate.send("test_direct_001", "test.123", message);
// 省略對 channel 的配置
rabbitTemplate.addListener(channel);

代碼解釋:

第 1 行,我們使用 rabbitTemplate 的 send 方法向 RabbitMQ Server 中發(fā)送了一條消息,其中,send 方法的第一個(gè)參數(shù)為綁定的交換機(jī),這里是 test_direct_001 ,第二個(gè)參數(shù)為 routingKey ,這里是 test.123,第三個(gè)參數(shù)為我們要發(fā)送的消息 message 。

第 3 行,我們使用 rabbitTemplate 的 addListener 方法,為當(dāng)前的消息模板添加了消息監(jiān)聽器,addListener 方法需要傳遞一個(gè) channel ,這個(gè)channel 需要我們事先配置好,就像介紹 Channel 小節(jié)那樣。

Tips: 1. send 方法和 convertAndSend 方法,區(qū)別之處在于,前者不會(huì)對消息進(jìn)行轉(zhuǎn)換,我們傳遞進(jìn)去的是什么消息,就會(huì)往 RabbitMQ Server 中發(fā)送什么消息;后者則會(huì)將我們傳遞進(jìn)去的消息進(jìn)行轉(zhuǎn)換,具體如何轉(zhuǎn)換的需要我們觀察源碼之后才會(huì)清楚,并將轉(zhuǎn)換過后的消息發(fā)送到 RabbitMQ Server中;\2. addListener 方法在 RabbitTemplate 中并不是使用頻率最高的,但確是經(jīng)常使用的一種消息監(jiān)聽的添加方法,如果我們不能在 convertAndSend 方法中添加消息監(jiān)聽,才會(huì)考慮使用 addListener 方法。

4. 小結(jié)

本小節(jié)為同學(xué)們介紹了在 Spring 生態(tài)中的 RabbitTemplate 消息模板。RabbitTemplate 作為 Spring-AMQP 中的消息模板,其發(fā)揮著重要的作用,RabbitTemplate 消息模板是連接應(yīng)用程序和 RabbitMQ Server 中間的橋梁,如果我們只配置了 RabbitAdmin ,沒有配置 RabbitTemplate ,那么我們的消息就無法發(fā)送到 RabbitMQ Server 中,也就沒法實(shí)現(xiàn)業(yè)務(wù)的閉環(huán)。

本小節(jié)詳細(xì)介紹了 RabbitTemplate 的基礎(chǔ)概念和作用,以及 RabbitTemplate 的基礎(chǔ)常用核心 API ,以及基礎(chǔ)配置的配置方法,對于這其中容易出現(xiàn)問題的地方也做了提示,旨在幫助同學(xué)們可以對 RabbitTemplate 有一個(gè)基礎(chǔ)的了解,并且要會(huì)使用 RabbitTemplate 進(jìn)行基本的消息發(fā)送和消息監(jiān)聽處理。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多