------------恢復內容開始------------html
在介紹RabbitMQ以前實現要介紹一下MQ,MQ是什麼?數據庫
MQ全稱是Message Queue,能夠理解爲消息隊列的意思,簡單來講就是消息以管道的方式進行傳遞。服務器
RabbitMQ是一個實現了AMQP(Advanced Message Queuing Protocol)高級消息隊列協議的消息隊列服務,用Erlang語言的。併發
在咱們秒殺搶購商品的時候,系統會提醒咱們稍等排隊中,而不是像幾年前同樣頁面卡死或報錯給用戶。tcp
像這種排隊結算就用到了消息隊列機制,放入通道里面一個一個結算處理,而不是某個時間斷忽然涌入大批量的查詢新增把數據庫給搞宕機,因此RabbitMQ本質上起到的做用就是削峯填谷,爲業務保駕護航。高併發
如今的市面上有不少MQ能夠選擇,好比ActiveMQ、ZeroMQ、Appche Qpid,那問題來了爲何要選擇RabbitMQ?工具
生產者、消費者和代理性能
在瞭解消息通信以前首先要了解3個概念:生產者、消費者和代理。ui
生產者:消息的建立者,負責建立和推送數據到消息服務器;操作系統
消費者:消息的接收方,用於處理數據和確認消息;
代理:就是RabbitMQ自己,用於扮演「快遞」的角色,自己不生產消息,只是扮演「快遞」的角色。
消息發送原理
首先你必須鏈接到RabbitMQ才能發佈和消費消息,那怎麼鏈接和發送消息的呢?
你的應用程序和Rabbit Server之間會建立一個TCP鏈接,一旦TCP打開,並經過了認證,認證就是你試圖鏈接Rabbit以前發送的Rabbit服務器鏈接信息和用戶名和密碼,有點像程序鏈接數據庫,使用Java有兩種鏈接認證的方式,後面代碼會詳細介紹,一旦認證經過你的應用程序和Rabbit就建立了一條AMQP信道(Channel)。
信道是建立在「真實」TCP上的虛擬鏈接,AMQP命令都是經過信道發送出去的,每一個信道都會有一個惟一的ID,不管是發佈消息,訂閱隊列或者介紹消息都是經過信道完成的。
1. TCP的建立和銷燬,開銷大,建立須要三次握手,銷燬須要四次分手。
2. 若是不使用信道,那麼引用程序就會使用TCP的方式鏈接到rabbitmq,高峯時每秒成千上萬條鏈接會形成資源的巨大浪費(一條tcp消耗資源,成千上萬的tcp會很是消耗資源),並且操做系統每秒處理TCP鏈接數量也是有限的,一定會形成性能瓶頸。
3.信道的原理是一條線程一條信道,多條線程多條信道共同使用一條TCP鏈接。一條TCP鏈接能夠容納無限的信道,及時每秒形成成千上萬的請求也不會形成性能瓶頸。
想要真正的瞭解Rabbit有些名詞是你必須知道的。
包括:ConnectionFactory(鏈接管理器)、Channel(信道)、Exchange(交換器)、Queue(隊列)、RoutingKey(路由鍵)、BindingKey(綁定鍵)。
ConnectionFactory(鏈接管理器):應用程序與Rabbit之間創建鏈接的管理器,程序代碼中使用;
Channel(信道):消息推送使用的通道;
Exchange(交換器):用於接受、分配消息;
Queue(隊列):用於存儲生產者的消息;
RoutingKey(路由鍵):用於把生成者的數據分配到交換器上;
BindingKey(綁定鍵):用於把交換器的消息綁定到隊列上;
看到上面的解釋,最難理解的路由鍵和綁定鍵了,那麼他們具體怎麼發揮做用的,請看下圖:
Rabbit隊列和交換器有一個不可告人的祕密,就是默認狀況下重啓服務器會致使消息丟失,那麼怎麼保證Rabbit在重啓的時候不丟失呢?答案就是消息持久化。
當你把消息發送到Rabbit服務器的時候,你須要選擇你是否要進行持久化,但這並不能保證Rabbit能從崩潰中恢復,想要Rabbit消息能恢復必須知足3個條件:
持久化工做原理
Rabbit會將你的持久化消息寫入磁盤上的持久化日誌文件,等消息被消費以後,Rabbit會把這條消息標識爲等待垃圾回收。
持久化的缺點
消息持久化的優勢顯而易見,但缺點也很明顯,那就是性能,由於要寫入硬盤要比寫入內存性能較低不少,從而下降了服務器的吞吐量,儘管使用SSD硬盤可使事情獲得緩解,但他仍然吸乾了Rabbit的性能,當消息成千上萬條要寫入磁盤的時候,性能是很低的。
因此使用者要根據本身的狀況,選擇適合本身的方式。
每一個Rabbit都能建立不少vhost,咱們稱之爲虛擬主機,每一個虛擬主機其實都是mini版的RabbitMQ,擁有本身的隊列,交換器和綁定,擁有本身的權限機制。
vhost特性
RabbitMQ默認的vhost是「/」開箱即用;
多個vhost是隔離的,多個vhost沒法通信,而且不用擔憂命名衝突(隊列和交換器和綁定),實現了多層分離;
建立用戶的時候必須指定vhost;
vhost操做(具體命令見下一章內容)
能夠經過rabbitmqctl工具命令建立:
rabbitmqctl add_vhost[vhost_name]
刪除vhost:
rabbitmqctl delete_vhost[vhost_name]
查看全部的vhost:
rabbitmqctl list_vhosts