1. 程式人生 > >保姆級別的RabbitMQ教程!一看就懂!(有安裝教程,送安裝需要的依賴包,送Java、Golang兩種客戶端教學Case)

保姆級別的RabbitMQ教程!一看就懂!(有安裝教程,送安裝需要的依賴包,送Java、Golang兩種客戶端教學Case)

[TOC] ### 什麼是AMQP 和 JMS? **AMQP**:即Advanced Message Queuing Protocol,是一個應用層標準高階訊息佇列協議,提供統一訊息服務。是應用層協議的一個開放標準,為面向訊息的中介軟體設計。基於此協議的客戶端與訊息中介軟體可傳遞訊息,並不受客戶端/中介軟體不同產品,不同的開發語言等條件的限制。**Erlang中的實現有RabbitMQ**等。 **JMS**:即Java訊息服務(Java Message Service)**應用程式介面**,由sun公司提出,並且sun公司定義好了介面。包括create、send、recieve。只要想使用它,就得實現它定義的介面。 訊息服務是一個與具體平臺無關的API,絕大多數MOM提供商都對JMS提供支援。不好的地方是語言層面的限制,只能為JAVA,這其實稍微有點和微服務的觀點相違背。要求語言只能是JAVA,而不能是py等。
### 常見的MQ產品 ActiveMQ:基於JMS,Apache RocketMQ:(Rocket,火箭)阿里巴巴的產品,基於JMS,目前由Apache基於會維護 Kafka:分散式訊息系統,亮點:吞吐量超級高,沒秒中數十萬的併發。 RabbitMQ:(Rabbit,兔子)由erlang語言開發,基於AMQP協議,在erlang語言特性的加持下,RabbitMQ穩定性要比其他的MQ產品好一些,而且erlang語言本身是面向高併發的程式設計的語言,所以RabbitMQ速度也非常快。且它基於AMQP協議,對分散式、微服務更友好。
### 安裝RabbitMQ 安裝使用的rpm包我提前準備好了,如下: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161943872-73638100.png) > 作業系統:Centos7.3 > > 推薦:這三個包我提前下載好了,關注白日夢的公眾號(文末有二維碼),後臺回覆:rbmq 可以直接領取。 > > 如果你不怕麻煩也想自己參照文件自行下載,可參考文末的連結。 科普一下: 比如你安裝軟體A,結果這個軟體可能依賴了軟體B,於是你直接安裝A就會接到報錯,說當前作業系統環境中缺少軟體B,讓你先安裝軟體B後,再嘗試安裝軟體A。 如果你看過Linux私房菜類似書,其實你應該也知道,rmp其實已經處理好各種依賴關係的軟體包,所以安裝起來相對來說是比較省心的。 ```bash # 安裝erlang yum install esl-erlang_23.0-1_centos_7_amd64.rpm -y yum install esl-erlang-compat-18.1-1.noarch.rpm -y # 安裝rabbitmq rpm -ivh rabbitmq-server-3.8.9-1.el7.noarch.rpm ``` 比如遇到如下的安裝包錯,按提示解決就好了 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161944779-1608734955.png) 下載依賴後重試即可完成安裝。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161945522-1464609833.png)
### 啟動RabbitMQ 通過如下命令可啟動: ```bash service rabbitmq-server start ``` ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161946301-1281632515.png) > 你可以像上面這樣,安裝之後立刻啟動。 > > 這時rabbitmq使用的是預設的配置引數。但是一般都來說我們都希望rabbitmq能使用我們可修改的配置檔案啟動,這樣也方便我們後續對mq的控制,下面就一起看一rabbitmq的認證、授權、訪問控制、配置檔案。 你還可以像下面這樣開啟web外掛。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161947200-884527400.png) 開啟web管理模組外掛之後訪問:http://伺服器的ip:15672/ 可以找到登陸入口。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161948163-2105817475.png) 設定rabbitmq開機啟動: ```bash chkconfig rabbitmq-server on ```
### 什麼是Authentication(認證) RabbitMQ啟動之後,我們想使用它的前提是用username、password連線上它。這裡所說的username和passowrd其實就是一個被授予一定許可權的使用者。 使用者連線上RabbitMQ即可建立virtual host使用MQ。在說什麼是virtual host之前,先說下RabbitMQ預設有的被授權的使用者:username=guest、password=guest、virtualhost=/。 但是這個使用者被限制了只能在RabbitMQ所在機器的本地才能登陸MQ(不允許你使用該使用者通過ip+port遠端登入RabbitMQ),就像下面這樣: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161949186-435456449.png) > 你使用特定的使用者去連線MQ的過程即為Authentication
### 指定RabbitMQ的啟動配置檔案 rabbitmq提供給我們一個配置檔案模版,預設在:`/usr/share/doc/rabbitmq-server-xxx/rabitmq.conf.example ` 如果你沒有找到的話也沒關係,去github上拷貝一份模版配置,手動建立 `/etc/rabbitmq/rabbitmq.conf` 配置檔案,然後將你拷貝的配置放進去也是ok的。 rabbitmq github addr:https://github.com/rabbitmq/rabbitmq-server/blob/v3.8.9/docs/ ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161951182-1995324790.png) > 涉及到的都是基礎的shell命令,不再贅述。 > > 注意檔名為:rabbitmq.config,且要放在/etc/rabbitmq目錄下。
### 如何讓guest使用者遠端登陸RabbitMQ 可以像下面這樣修改你的MQ的配置檔案: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161952296-434923127.png) 然後通過service命令重啟MQ,在web頁面嘗試登陸,接著你會成功登陸: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161954494-1546608916.png) > 官方:強烈不建議允許預設的使用者可遠端登陸MQ,用過RabbitMQ的程式設計師都知道預設使用者名稱和密碼是啥,這會讓你的系統的安全性大大降低! > > 推薦的做法是:刪除預設使用者、使用新的安全憑證建立新的使用者
### 管理使用者和許可權 其實文章看到這裡,什麼是使用者?什麼是許可權?你肯定已經非常清楚了。 那什麼是管理使用者和許可權?很簡單,就比如:新增/刪除 User,這個User可能屬於某個業務線,有了User可以使用RabbitMQ這款中介軟體軟體。以及為User分配他能讀寫的virtual host。 > 下一小節我們會細說什麼是 virtual host **本小節主要是通過實驗的方式展開,實戰Rabbit的使用者和許可權管理!** **主要有兩種方式:** **1、通過web控制檯管理 ** **2、通過cli命令列管理** 因為我們剛才允許guest這個超級管理員可以遠端登陸MQ,於是你可以像下圖這樣在web頁面上管理使用者,比如我可以為業務線A,新新增一個使用者changwu01,並且給他administrator的許可權,然後這個業務線通過該使用者使用MQ。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161955945-1616483470.png) 你也可以像下面這樣使用cli,通過命令列的方式新增使用者: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161956697-216581493.png) 然後使用該使用者嘗試登陸,你會發現:報錯了,說白日夢01不是管理員。不能登陸控制檯。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161957474-84312613.png) 如果你實戰一下,現將bairimeng01的許可權tags改成management,再嘗試登陸,它會提示你說: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161958451-327055998.png) 所以,這時你可以直接使用guest使用者登陸,然後將bairimeng01的許可權改成:administrator ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206161959582-418888312.png) 然後修改bairiemeng01的許可權,並點選update user ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162002559-703292331.png) 修改之後重新使用bairimeng01登陸: 你會發現bairimeng01可以成功登陸! ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162004268-1947252850.png) 檢視當前RabbitMQ有哪些使用者: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162006277-1114067871.png) 通過命令列建立使用者airimeng03、並通過命令列讓白日夢03有對virtualhost=/有讀寫權 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162006991-553395636.png) 可以通過控制檯確認一下,我們的配置確實生效了。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162008143-793402115.png)
### RabbitMQ中的概念
#### 什麼是virtual host 可以通過MySQL和MySQL中的資料庫來理解RabbitMQ和virtual host的關係。 MySQL大家都不陌生,經常會出現多個業務線混用一個MySQL資料庫的情況,就像下圖這樣,每個業務線都在MySQL中建立自己的資料庫,使用時各自往各自的資料庫中儲存資料,彼此相互不干涉。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162008852-1886576080.png) RabbitMQ和virtual host的關係也差不多,可以讓多個業務線同時使用一個RabbitMQ,只要為業務線各個業務線繫結上不同的virtual host即可: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162009680-1992407247.png)
#### 建立virtual host 並指定使用者可以使用它 Step1: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162010556-1179446240.png) Step2: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162011544-793083561.png) Step3: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162012923-103289151.png) Step4: 校驗 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162016640-682825445.png)
### RabbitMQ的五種訊息模型 RabbitMQ支援以下五種訊息模型,第六種RPC本質上是服務呼叫,所以不算做服務通訊訊息模型。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162020922-723030915.png) ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162022288-710990876.png)
#### Hello World ![](https://img2018.cnblogs.com/blog/1496926/201907/1496926-20190708125542629-2135674001.png) P(producer/ publisher):生產者,傳送訊息的服務 C(consumer):消費者,接收訊息的服務 紅色區域就是MQ中的Queue,可以把它理解成一個郵箱 - 首先信件來了不強求必須馬上馬去拿 - 其次,它是有最大容量的(受主機和磁碟的限制,是一個快取區) - 允許多個消費者監聽同一個佇列,爭搶訊息
#### Worker模型 ![](https://img2018.cnblogs.com/blog/1496926/201907/1496926-20190708125528529-1014015990.png) Worker模型中也只有一個工作佇列。但它是一種競爭消費模式。可以看到同一個佇列我們繫結上了多個消費者,消費者爭搶著消費訊息,**這可以有效的避免訊息堆積**。 比如對於簡訊微服務叢集來說就可以使用這種訊息模型,來了請求大家搶著消費掉。 如何實現這種架構:對於上面的HelloWorld這其實就是相同的服務我們啟動了多次罷了,自然就是這種架構。
#### 訂閱模型 訂閱模型藉助一個新的概念:Exchange(交換機)實現,不同的訂閱模型本質上是根據交換機(Exchange)的型別劃分的。 訂閱模型有三種 1. Fanout(廣播模型): 將訊息傳送給繫結給交換機的所有佇列(因為他們使用的是同一個RoutingKey)。 2. Direct(定向): 把訊息傳送給擁有指定Routing Key (路由鍵)的佇列。 3. Topic(萬用字元): 把訊息傳遞給擁有 符合Routing Patten(路由模式)的佇列。
##### 訂閱之Fanout模型 ![](https://img2018.cnblogs.com/blog/1496926/201907/1496926-20190708125522017-1931971535.png) 這個模型的特點就是它在傳送訊息的時候,並沒有指明Rounting Key , 或者說他指定了Routing Key,但是所有的消費者都知道,大家都能接收到訊息,就像聽廣播。
##### 訂閱之Direct模型 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162023832-709293422.png) P:生產者,向Exchange傳送訊息,傳送訊息時,會指定一個routing key。 X:Exchange(交換機),接收生產者的訊息,然後把訊息遞交給 與routing key完全匹配的佇列 C1:消費者,其所在佇列指定了需要routing key 為 error 的訊息 C2:消費者,其所在佇列指定了需要routing key 為 info、error、warning 的訊息 擁有不同的RoutingKey的消費者,會收到來自交換機的不同資訊,而不是大家都使用同一個Routing Key 和廣播模型區分開來。
##### 訂閱之Topic模型 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162025176-1413299944.png) 類似於Direct模型。區別是Topic的Routing Key支援萬用字元。
### JAVA客戶端 **後臺回覆:rbmq 即可獲取如下資料:** 本文中涉及到的:Golang Case、Java Case以及erlang虛擬機器rpm包、rabbitmq-server的rpm包等軟體,直接通過yum安裝即可。
#### Hello World 在本小節中你可以重點看一下當你通過程式碼建立連線、建立channel、傳送訊息、接受訊息的同時,在web view中,都有何變化。 Send.java: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162027761-836963960.png) 檢視新建立的連線: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162029902-1979813015.png) 檢視新建立的通道: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162031048-514403959.png) 檢視RabbitMQ中訊息的傳送狀態: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162032972-618368741.png) Recv.java: 執行如下的訊息接受者,可以收到傳送過來的訊息。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162034779-1703258400.png) 再去web view中觀察RabbitMQ中訊息的消費狀態: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162039411-1020592218.png) 檢視系統中連線的狀態,由於我沒有顯示的關閉連線和channl,所以你能看到系統中有兩個連線: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162041413-1940089877.png) channel也還存在: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162042914-1274161594.png)
#### Worker模型 ![](https://img2018.cnblogs.com/blog/1496926/201907/1496926-20190708125528529-1014015990.png) 本質上是相同的服務我們啟動了多次罷了,自然就是這種架構。 補充點1:可以給佇列新增一條屬性,不再是佇列把任務平均分配開給消費者。而是讓消費者消費完了後,問佇列要新的任務,這樣能者多勞。 ```java // 設定每個消費者同時只能處理一條訊息 channel.basicQos(1); ``` 補充點2:接受者接受訊息時,可以像下圖這樣配置手動ACK ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162044798-1424240893.png)
#### 訂閱模型 訂閱模型藉助一個新的概念:Exchange(交換機)實現,不同的訂閱模型本質上是根據交換機(Exchange)的型別劃分的。 訂閱模型有三種 1. Fanout(廣播模型): 將訊息傳送給繫結給交換機的所有佇列(因為他們使用的是同一個RoutingKey)。 2. Direct(定向): 把訊息傳送給擁有指定Routing Key (路由鍵)的佇列。 3. Topic(萬用字元): 把訊息傳遞給擁有 符合Routing Patten(路由模式)的佇列。
##### 訂閱之Fanout模型 ![](https://img2018.cnblogs.com/blog/1496926/201907/1496926-20190708125522017-1931971535.png) 這個模型的特點就是它在傳送訊息的時候,並沒有指明Rounting Key ,或者說他指定了Routing Key,但是所有的消費者都知道,大家都能接收到訊息,就像聽廣播。 傳送者: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162046322-1541772302.png) 去web view中檢視狀態: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162049035-1994412893.png) 執行接受者消費訊息 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162100938-754682181.png)
##### 訂閱之Direct模型 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162101853-1932156693.png) 和Fanout模型相似,傳送方傳送時:指定了routingkey如下 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162103919-1599898003.png) 接收方接受時,也指定了routingkey如下: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162105037-1970188598.png)
##### 訂閱之Topic模型 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162106143-697514166.png) topic模型和direc模型相似。 區別:交換機的型別:topic、routingkey:支援正則表示式 傳送者: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162107035-136786792.png) 接收者: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162108920-1603038968.png)
#### 訊息確認機制
##### ACK機制 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162109581-1996261690.png) 所謂的ACK確認機制: 自動ACK:消費者接收到訊息後自動傳送ACK給RabbitMQ。 手動ACK:我們手動控制消費者接收到併成功訊息後傳送ACK給RabbitMQ。 你可以看上圖:如果使用自動ACK,當訊息者將訊息從channel中取出後,RabbitMQ隨即將訊息給刪除。接著不幸的是,消費者沒來得及處理訊息就掛了。那也就意味著訊息其實丟失了。 你可能會說:會不會存在重複消費的情況呢?這其實就不是MQ的問題了。你完全可以在你程式碼的邏輯層面上進行諸如去重、插入前先檢查是否已存在等邏輯規避重複消費問題。 具體的實現方式可以參考上面的:JAVA客戶端/Worker模型
##### 持久化交換機 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162110162-847281033.png)
##### 持久化佇列 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162110748-548903954.png)
##### 持久化訊息 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162111757-631883304.png)
#### SpringAMQP SpringAMQP幫我們實現了--生產者確認機制,對於不可路由的訊息交換機會告訴生產者,使其重新發送
##### 環境搭建 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162112803-2731222.png) 配置檔案:生產者 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162113888-1601344803.png) 生產者使用**AmqpTemplate模板**傳送訊息 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162115231-1187736385.png) 消費端不需要AmqpTemplate模板傳送訊息,因此不配置 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162116366-1335675051.png) virtual-host,和當前使用者繫結的虛擬主機名, 這就Oralce裡面,不同限權的使用者可以看到的介面,擁有的能力是不用的,在RabbitMQ中,使用者只能看到和它相關的虛擬主機下面的資訊。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162117369-627723356.png)
### Golang客戶端 **關注白日夢,後臺回覆:rbmq 即可獲取如下資料:** 本文中涉及到的:Golang Case、Java Case以及erlang虛擬機器rpm包、rabbitmq-server的rpm包等軟體,直接通過yum安裝即可。 文末有二維碼 下載依賴包: ```go go get github.com/streadway/amqp ```
#### Hello World ![](https://img2018.cnblogs.com/blog/1496926/201907/1496926-20190708125542629-2135674001.png) 傳送端: Step1: 獲取連線: Dial最後面的`//test` 比較迷惑,其實`/test`是我的virtualhost,如果只寫成/host會把錯說:`"no access to this vhost"` ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162118616-1762612874.png) Step2: 建立channel ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162119555-1560946511.png) Step3: 宣告queue,後續往這個佇列中傳送訊息 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162120454-1005447851.png) Step5: 傳送訊息 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162121546-20732866.png) 接受端: 消費者同樣需要建立連線和channel、然後宣告我們想消費的channel,和上面的生產者程式碼相同,就不粘出來了。 消費者從channel中接受訊息: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162122634-1185039633.png) 處理訊息: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162123495-152901770.png)
#### Worker 模型 ![](https://img2018.cnblogs.com/blog/1496926/201907/1496926-20190708125528529-1014015990.png) 同樣的Worker模型和Simple模型也是相似的。無外乎是simple模型的消費者啟動了多個例項。 **訊息分發策略**:預設情況下RabbitMQ後將P生產的訊息以round-robin的策略分發給C1、C2。 你也可以像下圖這樣設定一個相對公平的分發策略: 當消費者把訊息處理完後MQ才會給他新的訊息,這樣可以實現能者多勞。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162126453-2081093643.png) **訊息確認機制**: 什麼是ACK機制,你可以往下翻看 Golang客戶端/訊息確認機制/ACK機制部分的描述。 如果手動ACK如下: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162131489-982184542.png) 當我們像上面這樣設定手動ACK之後,可以確保如果消費者沒處理完訊息就掛了,MQ中的訊息不會丟失。 但是如果這時MQ掛了,訊息同樣會丟失。 為了避免這種情況,可以將設定將MQ中的訊息也持久化 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162133103-2106115237.png)
#### 訂閱模型 訂閱模型藉助一個新的概念:Exchange(交換機)實現,不同的訂閱模型本質上是根據交換機(Exchange)的型別劃分的。 訂閱模型有三種 1. Fanout(廣播模型): 將訊息傳送給繫結給交換機的所有佇列(因為他們使用的是同一個RoutingKey)。 2. Direct(定向): 把訊息傳送給擁有指定Routing Key (路由鍵)的佇列。 3. Topic(萬用字元): 把訊息傳遞給擁有 符合Routing Patten(路由模式)的佇列。
##### 訂閱模型之Fanout模型 ![](https://img2018.cnblogs.com/blog/1496926/201907/1496926-20190708125522017-1931971535.png) 這個模型的特點就是它在傳送訊息的時候,並沒有指明Rounting Key , 或者說他指定了Routing Key,但是所有的消費者都知道,大家都能接收到訊息,就像聽廣播。 生產者:在獲取channel之後緊接著建立一個交換機,交換機的型別為 fanout 扇出。 注意,fanout對應的routingkey(路由key為空) ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162138515-433232868.png) 消費者:需要消費者獲取到channel後也要宣告交換機。消費者的queue無名稱,queue沒有routingkey。注意交換機的名字別寫錯。 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162140235-1447894593.png)
##### 訂閱模型之Direct模型 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162141800-646293539.png) 生產者:和Fanout類似,注意交換機的名稱為direct 以及新增 特定的routingkey ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162142798-374092395.png) 消費者: ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162143803-1234629713.png)
##### 訂閱模型之Topic模型 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162144760-1606745935.png) 和Direct模型相似,不同點:type為topic、並別routingkey支援正則表示式。 詳細程式碼不再重複貼了。可以自行領取原始碼學習。
#### 訊息確認機制
##### ACK機制 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162145404-1946623920.png) 所謂的ACK確認機制: 自動ACK:消費者接收到訊息後自動傳送ACK給RabbitMQ。 手動ACK:我們手動控制消費者接收到併成功訊息後傳送ACK給RabbitMQ。 你可以看上圖:如果使用自動ACK,當訊息者將訊息從channel中取出後,RabbitMQ隨即將訊息給刪除。接著不幸的是,消費者沒來得及處理訊息就掛了。那也就意味著訊息其實丟失了。 你可能會說:會不會存在重複消費的情況呢?這其實就不是MQ的問題了。你完全可以在你程式碼的邏輯層面上進行諸如去重、插入前先檢查是否已存在等邏輯規避重複消費問題。 具體的實現方式可以參考上面的Golang或JAVA客戶端的Worker模型部分。
##### 持久化交換機 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162146117-655440242.png)
##### 持久化佇列 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162146908-207929431.png)
##### 持久化訊息 ![](https://img2020.cnblogs.com/blog/1496926/202012/1496926-20201206162147852-227479855.png)
### 資料獲取 ![](https://img2020.cnblogs.com/blog/1496926/202011/1496926-20201115123042357-889631116.jpg) 本文中涉及到的:Golang Case、Java Case以及erlang虛擬機器rpm包、rabbitmq-server的rpm包等軟體,直接通過yum安裝即可。 關注後臺回覆:rbmq 即可獲取如下資料:

參考: 官網:https://www.rabbitmq.com/ get start:https://www.rabbitmq.com/getstarted.html download rabbitmq:https://www.rabbitmq.com/download.html rabbitmq和erlang版本對應關係:https://www.rabbitmq.com/which-erlang.html download erlang:https://www.erlang-solutions.com/resources/download.html rabbitmq推薦的erlang:https://www.rabbitmq.com/releases/erlang/ 瞭解更多rabbitmq3.8.X配置:https://www.cnblogs.com/masy-lucifer/p/13551067.html rabbitmq3.8.9 GitHub:https://github.com/rabbitmq/rabbitmq-server/tree/v3.8.9/docs 認證、授權、訪問控制:https://www.rabbitmq.com/access-cont