人一生最值得炫耀的不該該是你的財富有多少(雖然這話說得有點違心,呵呵),而是你的學習能力。技術更新迭代的速度很是快,那做爲程序員,咱們就應該擁有一顆擁抱變化的心,積極地跟進。html
在 RabbitMQ 入門以前,我已經入門了 Redis、Elasticsearch 和 MongoDB,這讓我感受本身富有極客精神,很是良好。java
小夥伴們在繼續閱讀以前,我必需要聲明一點,我對 RabbitMQ 並無進行很深刻的研究,僅僅是由於要用,就學一下。但做爲一名負責任的技術博主,我是動了心的,這篇入門教程,小夥伴們讀完後絕對會感到滿意,忍不住無情地點贊,以及赤裸裸地轉發。程序員
固然了,小夥伴們遇到文章中有錯誤的地方,不要手下留情,能夠組團過來捶我,但要保證一點,不要打臉,我怕毀容。web
首先,我知道,Rabbit 是一隻兔子(哎呀媽呀,忍不住秀了一波本身的英語功底),可愛的形象已經躍然於個人腦海中了。那 MQ 又是什麼呢?是 Message Queue 的首字母縮寫,也就是說 RabbitMQ 是一款開源的消息隊列系統。windows
RabbitMQ 的主要特色在於健壯性好、易於使用、高性能、高併發、集羣易擴展,以及強大的開源社區支持。反正就是很牛逼的樣子。數組
九年前我作大宗期貨交易的時候,也須要消息推送,那時候還不知道去找這種現成的中間件,就用自定義的隊列實現,結果搞了很多 bug,有些到如今尚未解決,真的是不堪回首的往事啊。瀏覽器
下圖是 RabbitMQ 的消息模型圖(來源於網絡,侵刪),小夥伴們來感覺下。bash
1)P 是 Producer,表明生產者,也就是消息的發送者,能夠將消息發送到 X服務器
2)X 是 Exchange(爲啥不是 E,我也很好奇),表明交換機,能夠接受生產者發送的消息,並根據路由將消息發送給指定的隊列微信
3)Q 是 Queue,也就是隊列,存放交換機發送來的消息
4)C 是 Consumer,表明消費者,也就是消息的接受者,從隊列中獲取消息
聽我這樣一解釋,是否是對 RabbitMQ 的印象就很具象化了?小夥伴們,學起來吧!
咦,怎麼不是安裝 RabbitMQ 啊?先來看看官方的解釋。
英文看不太懂,不要緊,我來補充兩人話。RabbitMQ 服務器是用 Erlang 語言編寫的,它的安裝包裏並無集成 Erlang 的環境,所以須要先安裝 Erlang。小夥伴們不要擔憂,Erlang 安裝起來沒有任何難度。
Erlang 下載地址以下:
https://erlang.org/download/otp_versions_tree.html
最新的版本是 23.0.1,我選擇的是 64 位的版本,104M 左右。下載完就能夠雙擊運行安裝,傻瓜式的。
須要注意的是,我安裝的過程當中,電腦重啓了一次,好像要安裝一個什麼庫,重啓以前忘記保存圖片了(sorry)。重啓後,從新雙擊運行 otp_win64_23.0.1.exe 文件完成 Erlang 安裝。
Erlang 安裝成功後,就能夠安裝 RabbitMQ 了。下載地址以下所示:
https://www.rabbitmq.com/install-windows.html
找到下圖中的位置,選擇紅色框中的文件進行下載。
安裝包只有 16.5M 大小,仍是很是輕量級的。下載完後直接雙擊運行 exe 文件就能夠傻瓜式地安裝了。
安裝成功後,就能夠將 RabbitMQ 做爲 Windows 服務啓動,能夠從「開始」菜單管理 RabbitMQ Windows 服務。
點擊「RabbitMQ Command Prompt (sbin dir)」,進入命令行,輸入 rabbitmqctl.bat status
可確認 RabbitMQ 的啓動狀態。
能夠看到 RabbitMQ 一些狀態信息:
命令行界面看起來不夠優雅,所以咱們能夠輸入如下命令來啓用客戶端管理 UI 插件:
rabbitmq-plugins enable rabbitmq_management
看到如下信息就能夠確認插件啓用成功了。
在瀏覽器地址欄輸入 http://localhost:15672/ 能夠進入管理端界面,以下圖所示:
有些小夥伴可能會問,「二哥,我是一名 Java 程序員,我該如何在 Java 中使用 RabbitMQ 呢?」這個問題問得好,這就來,這就來。
第一步,在項目中添加 RabbitMQ 客戶端依賴:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.9.0</version>
</dependency>
第二步,咱們來模擬一個最簡單的場景,一個生產者發送消息到隊列中,一個消費者從隊列中讀取消息並打印。
官方對 RabbitMQ 有一個很好的解釋,我就「拿來主義」的用一下。在我上高中的年代,同窗們之間最流行的交流方式不是 QQ、微信,甚至短信這些,而是書信。由於那時候尚未智能手機,何況上學期間學校也是命令禁用手機的,因此書信是情感表達的最好方式。好懷念啊。
假如我向女友小巷寫了一封情書,內容以下所示:
致小巷
你好呀,小巷。
你走了之後我天天都感到很悶,就像堂吉訶德同樣,天天想念託波索的達辛妮亞。我如今已經養成了一種習慣,就是每兩三天就要找你說幾句不想對別人說的話。
。。。。。。
王二,5月20日
那這封情書要寄給小巷,我就須要跑到郵局,買上郵票,投遞到郵箱當中。女友要收到這封情書,就須要郵遞員全力以赴,不要弄丟了。
RabbitMQ 就像郵局同樣,只不過處理的不是郵件,而是消息。以前解釋過了,P 就是生產者,C 就是消費者。
新建生產者類 Wanger :
public class Wanger {
private final static String QUEUE_NAME = "love";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "小巷,我喜歡你。";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
System.out.println(" [王二] 發送 '" + message + "'");
}
}
}
1)QUEUE_NAME 爲隊列名,也就是說,生產者發送的消息會放到 love 隊列中。
2)經過如下方式建立服務器鏈接:
ConnectionFactory factory = new ConnectionFactory();
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
ConnectionFactory 是一個很是方便的工廠類,可用來建立到 RabbitMQ 的默認鏈接(主機名爲「localhost」)。而後,建立一個通道( Channel)來發送消息。
Connection 和 Channel 類都實現了 Closeable 接口,因此可使用 try-with-resource 語句,若是有小夥伴對 try-with-resource 語句不太熟悉,能夠查看我以前寫的我去文章。
3)在發送消息的時候,必須設置隊列名稱,經過 queueDeclare()
方法設置。
4)basicPublish()
方法用於發佈消息:
生產者類有了,接下來新建消費者類 XiaoXiang:
public class XiaoXiang {
private final static String QUEUE_NAME = "love";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println("等待接收消息");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [小巷] 接收到的消息 '" + message + "'");
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
}
}
1)建立通道的代碼和生產者差很少,只不過沒有使用 try-with-resource 語句來自動關閉鏈接和通道,由於咱們但願消費者可以一直保持鏈接,直到咱們強制關閉它。
2)在接收消息的時候,必須設置隊列名稱,經過 queueDeclare() 方法設置。
3)因爲 RabbitMQ 將會經過異步的方式向咱們推送消息,所以咱們須要提供了一個回調,該回調將對消息進行緩衝,直到咱們作好準備接收它們爲止。
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [小巷] 接收到的消息 '" + message + "'");
};
basicConsume()
方法用於接收消息:
第一個參數爲隊列名(queue),和生產者相匹配(love)。
第二個參數爲 autoAck,若是爲 true 的話,代表服務器要一次性交付消息。怎麼理解這個概念呢?小夥伴們能夠在運行消費者類 XiaoXiang 類以前,先屢次運行生產者類 Wanger,向隊列中發送多個消息,等到消費者類啓動後,你就會看到多條消息一次性接收到了,就像下面這樣。
等待接收消息
[小巷] 接收到的消息 '小巷,我喜歡你。'
[小巷] 接收到的消息 '小巷,我喜歡你。'
[小巷] 接收到的消息 '小巷,我喜歡你。'
第三個參數爲 DeliverCallback,也就是消息的回調函數。
第四個參數爲 CancelCallback,我暫時沒搞清楚是幹嗎的。
在消息發送的過程當中,也可使用 RabbitMQ 的管理面板查看到消息的走勢圖,以下所示。
好了,我親愛的小夥伴們,以上就是本文的所有內容了,是否是看完後很想實操一把 RabbitMQ,趕快行動吧!若是你在學習的過程當中遇到了問題,歡迎隨時和我交流,雖然我也是個菜鳥,但我有熱情啊。
另外,若是你想寫入門級別的文章,這篇就是最好的範例。