一.什麼是消息隊列?何時使用它?web
在傳統的web架構中(此處特指Java SSM架構),用戶在web中進行了某項須要和後臺產生交互的操做後,通常都要開啓一個session,從view層開始,由controller層尋找相應的模型構件,找到相應的model後,生成相應的Java bean,再由Spring將bean映射到邏輯層,找到相關業務邏輯後,調用持久層框架,由數據庫進行數據操做。能夠看出,實際的業務邏輯十分複雜,在業務邏輯很少時尚可接受,但因爲大多數數據庫更新採用的是串行的方式,全部操做都須要在上一個操做完成後才能開始,就拿最多見的註冊帳號操做來講,常規操做下,用戶輸入基本信息之後,服務器響應時間咱們假設爲50ms,驗證驗證碼的正確也須要50ms,驗證手機號或者郵箱一樣須要50ms,那麼加起來就須要150ms。能夠看出,在數據庫操做數量增大後,即便是一個很是簡單的select操做,也須要產生不小的服務器負擔,一旦業務量也同時增大,極可能會形成服務器卡頓甚至宕機,給用戶帶來極差的體驗。而以前的解決方法,是使用cookie技術,即將數據存放到客戶端的瀏覽器上,但cookie技術雖然簡化了業務流程,隨之而來的是安全性的下降。某些居心不良的用戶可能會修改本地cookie,具備很大的安全隱患。(補充一句,也能夠經過對SQL自己的優化,經過調整行級鎖來達到最佳的鎖粒性,具體能夠參考《高性能mySQL》一書,本文不作贅述。)shell
所以,咱們引入了消息中間件(Message-oriented middleware,MOM)技術。消息代理服務器經過將用戶消息暫存到一個消息容器中,將一系列複雜的業務流程進行解耦,每一個模塊只須要完成它對應的功能,不須要關心別的模塊。畫一張圖以便你們理解。數據庫
能夠看到,經過使用MOM技術,咱們將本來可能須要150ms的業務流程縮短到了只須要70ms(實際上優化的時間會更多,由於RabbitMQ的特點正是響應時間極短,達到了微秒級)。同時,實現了業務的解耦,驗證手機號時不須要關心用戶此時有沒有經過驗證碼。固然,若是併發量太大,咱們能夠在超過消息隊列最大吞吐量後,選擇拋棄用戶請求,或者直接將用戶重定向至報錯頁面。根據採用技術的不一樣,最大吞吐量也有所不一樣,本文介紹的RabbitMQ可達到萬級,若是併發量大於萬級,能夠採用Kafka等技術。瀏覽器
固然,一種技術不可能只有優勢而沒有缺點。我我的對MOM的理解是這樣的,首先它確實對高併發場景有很大的幫助,好比雙十一等訪問量激增的時候,能夠有效幫助服務器進行錯峯。同時對各模塊進行解耦,使系統各模塊間的依賴度下降,不至於一個模塊掛了整個系統所有癱瘓。最後,MOM是一種異步請求,無需服務器響應就能夠發送下一個請求。可是,與之伴生的是,它對服務器壓力的激增,和一系列的現實問題。我打個比方,就拿雙十一搶購來講,假如採用了MOM技術,用戶下的訂單被存在消息隊列服務器上,此時,若是後臺的庫存臨時出現變化了,好比某我的下了不少訂單忽然退單了,因爲數據還沒有存入數據庫,其可能會產生一些影響,又或者說在後續的某個部分, 好比你下了訂單之後,後續的手機號填錯了,此時你已經經過了下單模塊,訂單信息已經存入了消息隊列服務器中,但後續本該異步的出現了錯誤,那可能就會出現髒讀的狀況。固然這些問題都是能夠經過一 系列預案,用複雜的邏輯判斷來規避的,但勢必增長了系統出錯的風險,由於系統的複雜性被大大地增長了。更須要注意的是,雖然系統各模塊間的依賴度下降了,但這是創建在對消息隊列服務器的依賴上的,若是消息隊列服務器掛了呢?因此,每項技術都有其應用場景,咱們應該根據實際使用狀況,來具體分析要不要使用MOM技術。安全
二.AMQ協議服務器
RabbitMQ基於AMQP規範,AMQP規範不只定義了一種網絡協議,也定義了服務器端的服務和行爲。這就是高級消息隊列(Advanced Message Queuing,AMQ)模型,其在邏輯上定義了三種抽象組件用於指定消息的路由行爲:cookie
·交換器(Exchange),消息代理服務器中用於把消息路由到隊列的組件。網絡
·隊列(Queue),用來存儲消息的數據結構,位於硬盤或內存中。session
·綁定(Binding),一套規則,用於告訴交換器消息應該被存儲到哪一個隊列。數據結構
一個AMQP能夠有多個信道,容許服務器和客戶端之間進行屢次通訊,這就是多路複用。須要注意的是,在嘗試聲明一個與現有隊列同名的信道時,若是新隊列的屬性與現有隊列不同,那麼RabbitMQ將關閉RPC請求的信道。 要正確處理錯誤,你的客戶端應用程序應該監聽來自RabbitMQ的Channel.Close命令,以便可以正確響應。有的客戶端可能會經過在Channel.Close命令註冊一個回調方法來自動觸發。
低層AMQP幀是由五個不一樣的組件構成的,其分別是: