MQ全稱爲Message Queue, 消息隊列(MQ)是一種應用程序對應用程序的通訊方法。應用程序經過讀寫出入隊列的消息(針對應用程序的數據)來通訊,而無需專用鏈接來連接它們。消息傳遞指的是程序之間經過在消息中發送數據進行通訊,而不是經過直接調用彼此來通訊,直接調用一般是用於諸如遠程過程調用的技術。排隊指的是應用程序經過 隊列來通訊。隊列的使用除去了接收和發送應用程序同時執行的要求。數據庫
RabbitMQ是使用Erlang語言開發的開源消息隊列系統,基於AMQP協議來實現。AMQP的主要特徵是面向消息、隊列、路由(包括點對點和發佈/訂閱)、可靠性、 安全。AMQP協議更多用在企業系統內,對數據一致性、穩定性和可靠性要求很高的場景,對性能和吞吐量的要求還在其次。瀏覽器
1. 解耦(爲面向服務的架構(SOA)提供基本的最終一致性實現)緩存
場景說明:用戶下單後,訂單系統須要通知庫存系統。傳統的作法是,訂單系統調用庫存系統的接口。安全
傳統模式的缺點:服務器
假如庫存系統沒法訪問,則訂單減庫存將失敗,從而致使訂單失敗架構
訂單系統與庫存系統耦合併發
引入消息隊列app
訂單系統:用戶下單後,訂單系統完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功異步
庫存系統:訂閱下單的消息,採用拉/推的方式,獲取下單信息,庫存系統根據下單信息,進行庫存操做ide
假如:在下單時庫存系統不能正常使用。也不影響正常下單,由於下單後,訂單系統寫入消息隊列就再也不關心其餘的後續操做了。實現訂單系統與庫存系統的應用解耦
爲了保證庫存確定有,能夠將隊列大小設置成庫存數量,或者採用其餘方式解決。
基於消息的模型,關心的是「通知」,而非「處理」。
短信、郵件通知、緩存刷新等操做使用消息隊列進行通知。
消息隊列和RPC的區別與比較:
RPC: 異步調用,及時得到調用結果,具備強一致性結果,關心業務調用處理結果。
消息隊列:兩次異步RPC調用,將調用內容在隊列中進行轉儲,並選擇合適的時機進行投遞(錯峯流控)
2. 異步提高效率
場景說明:用戶註冊後,須要發註冊郵件和註冊短信。傳統的作法有兩種 1.串行的方式;2.並行方式
(1)串行方式:將註冊信息寫入數據庫成功後,發送註冊郵件,再發送註冊短信。以上三個任務所有完成後,返回給客戶端
(2)並行方式:將註冊信息寫入數據庫成功後,發送註冊郵件的同時,發送註冊短信。以上三個任務完成後,返回給客戶端。與串行的差異是,並行的方式能夠提升處理的時間
(3)引入消息隊列,將不是必須的業務邏輯,異步處理。改造後的架構以下:
3. 流量削峯
流量削鋒也是消息隊列中的經常使用場景,通常在秒殺或團搶活動中使用普遍
應用場景:系統其餘時間A系統每秒請求量就100個,系統能夠穩定運行。系統天天晚間八點有秒殺活動,每秒併發請求量增至1萬條,可是系統最大的處理能力只能每秒處理1000個請求,因而系統崩潰,服務器宕機。
以前架構:大量用戶(100萬用戶)經過瀏覽器在晚上八點高峯期同時參與秒殺活動。大量的請求涌入咱們的系統中,高峯期達到每秒鐘5000個請求,大量的請求打到MySQL上,每秒鐘預計執行3000條SQL。可是通常的MySQL每秒鐘扛住2000個請求就不錯了,若是達到3000個請求的話可能MySQL直接就癱瘓了,從而系統沒法被使用。可是高峯期過了以後,就成了低峯期,可能也就1萬用戶訪問系統,每秒的請求數量也就50個左右,整個系統幾乎沒有任何壓力。
引入MQ:100萬用戶在高峯期的時候,每秒請求有5000個請求左右,將這5000請求寫入MQ裏面,系統A每秒最多隻能處理2000請求,由於MySQL每秒只能處理2000個請求。系統A從MQ中慢慢拉取請求,每秒就拉取2000個請求,不要超過本身每秒能處理的請求數量便可。MQ,每秒5000個請求進來,結果只有2000個請求出去,因此在秒殺期間(將近一小時)可能會有幾十萬或者幾百萬的請求積壓在MQ中。這個短暫的高峯期積壓是沒問題的,由於高峯期過了以後,每秒就只有50個請求進入MQ了,可是系統仍是按照每秒2000個請求的速度在處理,因此說,只要高峯期一過,系統就會快速將積壓的消息消費掉。咱們在此計算一下,每秒在MQ積壓3000條消息,1分鐘會積壓18萬,1小時積壓1000萬條消息,高峯期事後,1個多小時就能夠將積壓的1000萬消息消費掉。
優勢
優勢就是以上的那些場景應用,就是在特殊場景下有其對應的好處,解耦、異步、削峯。
缺點
系統的可用性下降
系統引入的外部依賴越多,系統越容易掛掉,原本只是A系統調用BCD三個系統接口就好,ABCD四個系統不報錯整個系統會正常運行。引入了MQ以後,雖然ABCD系統沒出錯,但MQ掛了之後,整個系統也會崩潰。
系統的複雜性提升
引入了MQ以後,須要考慮的問題也變得多了,如何保證消息沒有重複消費?如何保證消息不丟失?怎麼保證消息傳遞的順序?
一致性問題
A系統發送完消息直接返回成功,可是BCD系統之中如有系統寫庫失敗,則會產生數據不一致的問題。
因此總結來講,消息隊列是一種十分複雜的架構,引入它有不少好處,可是也得針對它帶來的壞處作各類額外的技術方案和架構來規避。引入MQ系統複雜度提高了一個數量級,可是在有些場景下,就是複雜十倍百倍,仍是須要使用MQ。
感謝你們看到這裏,若是本文有什麼不足之處,歡迎多多指教;若是你以爲對你有幫助,請給我點個贊。