消息隊列_基本概念


  消息隊列(Message Queue,簡稱MQ),從字面意思上看,本質是個隊列,FIFO先入先出,只不過隊列中存放的內容是message而已。其主要用途:不同進程Process/線程Thread之間通信。為什么會產生消息隊列?這個問題問的好,我大概查了一下,沒有查到最初產生消息隊列的背景,但我猜測可能幾個原因:

  • 不同進程(process)之間傳遞消息時,兩個進程之間耦合程度過高,改動一個進程,引發必須修改另一個進程,為了隔離這兩個進程,在兩進程間抽離出一層(一個模塊),所有兩進程之間傳遞的消息,都必須通過消息隊列來傳遞,單獨修改某一個進程,不會影響另一個;
  • 不同進程(process)之間傳遞消息時,為了實現標准化,將消息的格式規范化了,並且,某一個進程接受的消息太多,一下子無法處理完,並且也有先后順序,必須對收到的消息進行排隊,因此誕生了事實上的消息隊列

  不管到底是什么原因催生了消息隊列,總之,上面兩個猜測是其實際應用的典型場景。

   通過消息隊列,將短時間高並發產生的事務消息存儲在消息隊列中,從而削平高峰期的並發事務,改善網站系統的性能。在京東之類的電子商務網站促銷活動中,合理地使用消息    隊列,可以有效地抵御促銷活動剛開始就開始大量涌入的訂單對系統造成的沖擊

  切合前一部分猜測的消息隊列產生背景,其主要解決兩個問題:

  • 系統解耦:項目開始時,無法確定最終需求,不同進程間,添加一層,實現解耦,方便今后的擴展。
  • 消息緩存:系統中,不同進程處理消息速度不同,MQ,可以實現不同Process之間的緩沖,即,寫入MQ的速度可以盡可能地快,而處理消息的速度可以適當調整(或快、或慢)。

     

  下面針對系統解耦消息緩存兩點,來分析實際應用消息隊列過程中,可能遇到的問題。虛擬場景:Process_A通過消息隊列MQ_1向Process_B傳遞消息,幾個問題:

  • 針對MQ_1中一條消息message_1,如何確保Process_B從MQ_1中只取一次message_1,不會重復多次取出message_1?
  • 如果MQ_1中message_1已經被Process_B取出,正在處理的關鍵時刻,Process_B崩潰了,哭啊,我的問題是,如果重啟Process_B,是否會丟失message_1?

  不要着急,閱讀了下面的簡要介紹后,水到渠成,上面幾個問題就可以解決了。 消息隊列有如下幾個好處,這大都是由其系統解耦消息緩存兩點擴展而來的:

  • 提升系統可靠性:
    • 冗余:Process_B崩潰之后,數據並不會丟失,因為MQ多采用put-get-delete模式,即,僅當確認message被完成處理之后,才從MQ中移除message;
    • 可恢復:MQ實現解耦,部分進程崩潰,不會拖累整個系統癱瘓,例,Process_B崩潰之后,Process_A仍可向MQ中添加message,並等待Process_B恢復;
    • 可伸縮:有較強的峰值處理能力,通常應用會有突發的訪問流量上升情況,使用足夠的硬件資源時刻待命,空閑時刻較長,資源浪費,而消息隊列卻能夠平滑峰值流量,緩解系統組件的峰值壓力;
  • 提升系統可擴展性:
    • 調整模塊:由於實現解耦,可以很容易調整,消息入隊速率、消息處理速率、增加新的Process;
  • 其他:
    • 單次送達:保證MQ中一個message被處理一次,並且只被處理一次。本質:get獲取一個message后,這一message即被預定,同一進程不會再次獲取這一message;當且僅當進程處理完這一message后,MQ中會delete這個message。否則,過一段時間后,這一message自動解除被預訂狀態,進程能夠重新預定這個message;
    • 排序保證:即,滿足隊列的FIFO,先入先出策略;
    • 異步通信:很多場景下,不會立即處理消息,這是,可以在MQ中存儲message,並在某一時刻再進行處理;
    • 數據流的階段性能定位:獲取用戶某一操作的各個階段(通過message來標識),捕獲不同階段的耗時,可用於定位系統瓶頸。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM