一、什麼是RabbitMQ
RabbitMQ是實作了進階消息隊列協定(AMQP)的開源消息代理軟體(亦稱面向消息的中間件),RabbitMQ伺服器是用Erlang語言編寫的。
二、為什麼使用RabbitMQ
1、可靠性:RabbitMQ可以通過持久化、傳輸确認及釋出确認來保證可靠性。
2、解耦:Rabbitmq中間件減少了應用程式之間的強依賴,舉個例子:電商背景要删除某個産品,除了要delete資料庫資料,還要通知CMS,如果通知CMS的操作使用RabbitMQ,那麼電商背景删除産品的應用程式就不需要等待CMS響應。
3、持久化:消息中間件支援資料持久化。如果通知CMS失敗,那麼通知資訊會被持久化,直到能夠通知到CMS為止。
4、擴充性:多個RabbitMQ節點可以組成一個叢集,也可以根據實際業務情況動态地擴充叢集中節點。
5、削峰:對于突發的大通路壓力,使用消息中間件采用隊列的形式可以減少突發通路壓力,不會因為突發的逾時負荷要求而崩潰。
6、可恢複性:消息中間件降低了程序間的耦合性,當一個處理消息的程序挂掉後,加入消息中間件的消息仍然可以在系統恢複後重新處理
7、順序保證:RabbitMQ就是消息隊列的實作,消息隊列的特點就是先進先出,是以有順序保證。
8、異步通信:通過把把消息發送給消息中間件,消息中間件并不立即處理它,後續在慢慢處理。
9、多種協定:RabbitMQ除了原生支援AMQP協定,還支援STOMP,MQTT等多種消息中間件協定。
10、管理界面:RabbitMQ提供了一個易用的使用者界面,使得使用者可以監控和管理消息、叢集中的節點。
11、多語言用戶端:RabbitMQ幾乎支援所有常用語言,比如Java、Python、Ruby、PHP、C#、JavaScript。
總結一句話rabbitmq主要的作用:削峰、解耦、異步。
三、RabbitMQ的原理
1、RabbitMQ中設計的名詞解釋
(1)Producer(生産者):生産者和消費者都是RabbitMQ的用戶端,生産者就是為了生産消息。
(2)Consumer(消費者):生産者和消費者都是RabbitMQ的用戶端,消費者就是資料的接收方,消費者從queue中取資料。
(3)Broker:RabbbitMQ消息隊列代理伺服器實體。
(4)Vhost(虛拟主機):一個Broker裡可以開設多個vhost,用作不同使用者的權限分離。
(5)Message:傳輸的消息體,由payload和label組成,payload是傳輸的消息資料,label是exchange的名字,作為tag。
(6)Exchanges:Producer發送的消息會通過Exchange根據相應的規則分發到queue。
(7)Binding(綁定):指定交換器和隊列之間的關系,就是把exchange和queue按照路由規則綁定起來。
(8)Queue:用來存儲消息的地方,由Consumer進行消費,消費之後queue的這個消息就被删除掉了。
(9)Routing Key(路由關鍵字):exchange根據Routing Key将消息投放到相應隊列。
(10)Connection:Producer和Consumer這兩個用戶端都是通過TCP連接配接到某個虛拟主機。
(11)Channel(消息通道):包含了大量的API可用于程式設計。在用戶端的每個連接配接裡,可建立多個channel,每個channel代表一個會話任務。也就是說,一般情況是程式起始建立TCP連接配接,第二步就是建立這個Channel。目的是保持長連接配接,減少tcp建立的性能損耗。
(12)ConnectionFactory:連接配接工廠類,可以建立一個連接配接。
(13)Acknowledged(ack):Consumer将消息消費完畢後給server的回執确認,Server确認後會把消息從queue中删除。
(14)Direct:Exchange的一種類型,如果 routing key 比對, 那麼Message就會被傳遞到相應的queue中。
(15)Fanout: Exchange的一種類型,所有與exchange關聯的queue都會被傳遞。
(16)Topic: Exchange的一種類型,按照routingkey規則比對的queue 。
2、RabbitMQ流程圖(來自于百度圖檔)

3、RabbitMQ原理描述
假設Producer1和Consumer1注冊了相同的Broker,Exchange和Queue。Producer1發送的消息最終會被Consumer1消費。基本的通信流程如下:
(1)Producer1生産消息,發送給伺服器端的Exchange
(2)Exchange收到消息,根據Routing Key,将消息轉發給比對的Queue1
(3)Queue1收到消息,将消息發送給訂閱者Consumer1
(4)Consumer1收到消息,發送ACK給隊列确認收到消息
(5)Queue1收到ACK,删除隊列中緩存的此條消息
4、注意事項
Consumer收到消息時需要顯式的向Rabbit Broker發送ack消息或者Consumer訂閱消息時設定auto_ack參數為true。在通信過程中,隊列對ACK的處理有以下幾種情況:
(1)如果Consumer接收了消息,發送ack,Rabbitmq會删除隊列中這個消息,發送另一條消息給Consumer。
(2)如果Cosumer接受了消息, 但在發送ack之前斷開連接配接,Rabbitmq會認為這條消息沒有被Deliver,在Consumer在次連接配接的時候,這條消息會被Redeliver。
(3)如果Consumer接受了消息,但是程式中有Bug,忘記了ack,Rabbitmq不會重複發送消息。
(4)Rabbitmq2.0.0和之後的版本支援Consumer通過設定Requeue參數中的reject為true 拒絕某條消息,那麼Rabbitmq将會把消息發送給下一個注冊的Consumer。
四、RabbitMQ的應用場景
RabbitMQ的集中典型應用可以參考RabbitMQ的幾種典型使用場景