消息發(fā)送模式實(shí)戰(zhàn)之普通隊(duì)列模式與工作隊(duì)列模式
1. 前言
Hello,大家好。在上述小節(jié)中,我們對(duì) RabbitMQ 中的發(fā)布訂閱消息發(fā)送模式的實(shí)戰(zhàn)內(nèi)容進(jìn)行了介紹,并針對(duì)不同的業(yè)務(wù)場(chǎng)景進(jìn)行了代碼實(shí)現(xiàn)。在本小節(jié)中,我們將對(duì) RabbitMQ 中消息發(fā)送模式的最后兩種模式的實(shí)戰(zhàn)內(nèi)容進(jìn)行介紹。
本小節(jié)會(huì)介紹 RabbitMQ 中最后的兩種消息發(fā)送模式的實(shí)戰(zhàn)部分,包括普通隊(duì)列模式的基礎(chǔ)概念回顧與代碼實(shí)現(xiàn),以及工作隊(duì)列模式的基礎(chǔ)概念回顧與代碼實(shí)現(xiàn),在將這兩部分的實(shí)戰(zhàn)內(nèi)容介紹完畢之后,RabbitMQ 中所有的消息發(fā)送模式中的實(shí)戰(zhàn)內(nèi)容就全部介紹完畢了。
本節(jié)主要內(nèi)容:
-
普通隊(duì)列模式與工作隊(duì)列模式基礎(chǔ)概念回顧;
-
普通隊(duì)列模式與工作隊(duì)列模式代碼實(shí)操。
2.普通隊(duì)列模式與工作隊(duì)列模式基礎(chǔ)概念回顧
在我們正式開(kāi)始使用代碼進(jìn)行實(shí)戰(zhàn)之前,讓我們先來(lái)回顧一下普通隊(duì)列模式與工作隊(duì)列模式的基礎(chǔ)概念等相關(guān)內(nèi)容。
2.1 普通隊(duì)列模式基礎(chǔ)概念回顧
定義:
普通隊(duì)列模式,即最簡(jiǎn)單的消息發(fā)送模式,不使用任何交換機(jī),由生產(chǎn)者、隊(duì)列、消費(fèi)者組合完成消息的發(fā)送和接收。
描述:
普通隊(duì)列模式,由于其操作簡(jiǎn)單,所以又被稱(chēng)為簡(jiǎn)單模式,如下圖所示:

普通隊(duì)列模式,在生產(chǎn)者生產(chǎn)完消息之后,直接將消息發(fā)送到隊(duì)列中去,不經(jīng)過(guò)交換機(jī)進(jìn)行處理,然后由消費(fèi)者直從消息隊(duì)列中獲取消息并消費(fèi)。在這個(gè)過(guò)程中間,沒(méi)有我們需要特別注意的地方。
2.2 工作隊(duì)列模式基礎(chǔ)概念回顧
定義:
工作隊(duì)列模式,和普通隊(duì)列模式有點(diǎn)像,都是不使用任何交換機(jī),由生產(chǎn)者、隊(duì)列、消費(fèi)者組合完成消息的發(fā)送和接收,只不過(guò)工作隊(duì)列支持存在多個(gè)消費(fèi)者,而普通隊(duì)列模式只支持一個(gè)消費(fèi)者。
描述:

工作隊(duì)列模式下,生產(chǎn)者生產(chǎn)出消息后,直接將消息發(fā)送到消息隊(duì)列中,然后多個(gè)消費(fèi)者按照一個(gè)隨機(jī)的順序來(lái)依次獲取消息并消費(fèi)。
存在多個(gè)消費(fèi)者消費(fèi)消息時(shí),下一個(gè)消費(fèi)者只能等待上一個(gè)消費(fèi)者消費(fèi)結(jié)束后才能獲取到消息并進(jìn)行消費(fèi)。
這就提示我們,在實(shí)際工作中,我們可以把費(fèi)時(shí)的業(yè)務(wù)操作交給 RabbitMQ 去做,這樣可以提升代碼的執(zhí)行效率。
Tips:
1. 無(wú)論是普通隊(duì)列模式,還是工作隊(duì)列模式,其操作相對(duì)來(lái)說(shuō)都比較簡(jiǎn)單,適合很簡(jiǎn)單的業(yè)務(wù)場(chǎng)景,同時(shí),初學(xué)者更易于理解。
2. 工作隊(duì)列模式和發(fā)布訂閱模式的功能很相似,都是用于消息需要進(jìn)行群發(fā)的場(chǎng)景,對(duì)于這兩種模式,我們?cè)趯?shí)際工作中應(yīng)該仔細(xì)斟酌,到底使用哪種消息發(fā)送模式最合適。
3 普通隊(duì)列模式與工作隊(duì)列模式
3.1 普通隊(duì)列模式代碼實(shí)操
在回顧完普通隊(duì)列模式的基礎(chǔ)概念之后,讓我們來(lái)看一下如何使用代碼來(lái)實(shí)現(xiàn)這種普通隊(duì)列模式:
實(shí)現(xiàn)代碼:
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.close();
connection.close();
代碼解釋?zhuān)?/strong>
第 1-5 行,我們使用了 RabbitMQ 的 ConnectionFactory 連接工廠,來(lái)初始化了一些獲取 RabbitMQ 連接的必要參數(shù)。
第 6 行,我們從 RabbitMQ 的連接工廠中,獲取到了一個(gè) RabbitMQ Conneciton 連接實(shí)例。
第 7 行,我們通過(guò) RabbitMQ 連接實(shí)例,創(chuàng)建了一個(gè) channel 通道,為之后的消息通信提供媒介。
第 8 行,我們使用 channel 的 queueDeclare 方法,來(lái)聲明一個(gè)消息隊(duì)列,并綁定到我們的 channel 頻道上。
第 9-10 行,在處理完通道與連接實(shí)例之后,我們分別調(diào)用了 close 方法,將建立的通信連接和通道進(jìn)行關(guān)閉,以節(jié)省資源開(kāi)銷(xiāo)。
由于普通隊(duì)列模式不需要交換機(jī)的參與,只需要一個(gè)生產(chǎn)者、一個(gè)消費(fèi)者,還有一個(gè)消息隊(duì)列,即可完成,這就是普通隊(duì)列模式。
3.2 工作隊(duì)列模式代碼實(shí)操
我們來(lái)看工作隊(duì)列模式的代碼實(shí)現(xiàn):
實(shí)現(xiàn)代碼:
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,byte[] body) throws IOException {
String msg = new String(body, "UTF-8");
// 業(yè)務(wù)處理
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
channel.close();
connection.close();
代碼解釋?zhuān)?/strong>
第 1-7 行,代碼和第一種業(yè)務(wù)場(chǎng)景相似,這里不再贅述。
第 8-16 行,我們通過(guò)使用 new DefaultConsumer 匿名內(nèi)部類(lèi)的形式,來(lái)依次從消息隊(duì)列中獲取消息,在獲取到消息之后,我們可以再 handleDevelivery 方法中處理我們的業(yè)務(wù)邏輯。
第 17 行,我們使用 channel 的 basicConsume 方法來(lái)將我們獲取到的消息進(jìn)行一個(gè)消費(fèi)。
事實(shí)上,我們應(yīng)該使用 for 循環(huán),或者動(dòng)態(tài)獲取的方式,來(lái)指定我們工作隊(duì)列模式中,所需要的消費(fèi)者數(shù)量,這樣我們才能實(shí)現(xiàn)一種沒(méi)有交換機(jī)的消息群發(fā)模式,這就是工作隊(duì)列模式。
Tips: 我們可以發(fā)現(xiàn),在實(shí)現(xiàn)普通隊(duì)列模式和工作隊(duì)列模式時(shí),我們并沒(méi)有指定 Routing Key ,因?yàn)檫@兩種消息發(fā)送模式不需要指定,這里需要同學(xué)們注意。
4. 小結(jié)

本小節(jié)為同學(xué)們?cè)敿?xì)介紹了 RabbitMQ 消息發(fā)送模式之普通隊(duì)列模式和工作隊(duì)列模式的代碼實(shí)操等內(nèi)容,包括普通隊(duì)列模式和工作隊(duì)列模式基礎(chǔ)概念等內(nèi)容的回顧,以及普通隊(duì)列模式和工作隊(duì)列模式的代碼實(shí)現(xiàn),同學(xué)們需要理清代碼實(shí)現(xiàn)的思路和步驟。
寫(xiě)到這里,我們對(duì) RabbitMQ 中常見(jiàn)的 5 種消息發(fā)送模式的實(shí)戰(zhàn)內(nèi)容部分就全部介紹完畢了,在實(shí)際工作中,我們需要結(jié)合具體的業(yè)務(wù)場(chǎng)景,以及我們這些消息發(fā)送模式的基礎(chǔ)概念去篩選合適的消息發(fā)送模式,來(lái)完成我們的需求,這并不是一個(gè)隨便選擇的過(guò)程。