RabbitMQ學習筆記

1.消息中間件的核心設計思想
    採用異步通訊、自動補償與重試分佈式事務、解決流量削峯問題、系統的解耦

2.消息中間件常用名詞:
    Broker 消息轉發端,消息中間件Server端;
    Message 發送的消息內容
    roducer 生產者,向Server端投遞消息;
    Consumer 消費者,向Server端獲取消息
    MessageId 消息全局id  解決消息冪等性問題    
    
3.主流的MQ對比分析
    ActiveMQ: 基本淘汰(老項目使用) 夠輕巧(源代碼比RocketMQ多),支持持久化到數據庫,
                  對隊列數較多的情況支持不好。
    RabbitMQ: 結合erlang語言本身的併發優勢,支持很多的協議:AMQP,XMPP, SMTP, STOMP,
                  也正是如此,使的它變的非常重量級,更適合於企業級的開發。
    RocketMQ: 阿里系下開源的一款分佈式、隊列模型的消息中間件,原名Metaq,3.0版本名稱改爲RocketMQ,
                  是阿里參照kafka設計思想使用java實現的一套mq,同時將阿里系內部多款mq產品
                  (Notify、metaq)進行整合,只維護核心功能,去除了所有其他運行時依賴,
                  保證核心功能最簡化,在此基礎上配合阿里上述其他開源產品實現不同場景下mq的架構,
                  目前主要多用於訂單交易系統。
    Kafka:    Apache下的一個子項目,使用scala實現的一個高性能分佈式Publish/Subscribe消息隊列系統,
                具有以下特性:高吞吐:在一臺普通的服務器上既可以達到10W/s的吞吐速率;
                高堆積:支持topic下消費者較長時間離線,消息堆積量大;

4.RabitMQ環境的基本安裝
    1.下載並安裝erlang,下載地址:http://www.erlang.org/download
    2.配置erlang環境變量信息
          新增環境變量ERLANG_HOME=erlang的安裝地址
          將%ERLANG_HOME%\bin加入到path中
    3.下載並安裝RabbitMQ,下載地址:http://www.rabbitmq.com/download.html
          注意: RabbitMQ 它依賴於Erlang,需要先安裝Erlang。                
          
5.Virtual Hosts:
    像mysql有數據庫的概念並且可以指定用戶對庫和表等操作的權限。那RabbitMQ呢?
    RabbitMQ也有類似的權限管理。在RabbitMQ中可以虛擬消息服務器VirtualHost,每
    個VirtualHost相當月一個相對獨立的RabbitMQ服務器,每個VirtualHost之間是相互
    隔離的。exchange、queue、message不能互通。

6.公平隊列實現原理
    Mq服務器端每次只會給消費者發送一條消息,如果消費者沒有返回ack,就不會繼續發送消
    息。
    
7.如何保證消息不丟失
    1.生產者 確保我們的生產者將消息投遞到MQ成功; 消息確認機制如果開啓了消息持久化的機制,必須消息持久化成功纔會應答給生產者
        // 開啓生產確認消息投遞機制   channel.confirmSelect();
         channel.waitForConfirms()==true  投遞成功
    2.消費者 確保我們的消費者消費消息成功 採用手動ack確認
    3.MQ服務器端 需要將數據持久化到我們的硬盤
  其他情況下:  硬盤壞了、持久化的過程斷電了?    
    如何解決 最好通過表記錄每次生產者投遞消息,如果長期沒有被消費,手動的補償消費。
    
8.如果在生產者投遞消息失敗的情況,在那些場景?
    1.MQ掛了 解決做心跳檢測(heartbeat),自動重啓,多次重啓失敗發郵件運維
    2.Mq拒絕接受消息 (隊列滿了) 就採用手動補償或者日誌表記錄下即可

9.Rabbitmq如何開啓持久化的功能?
    1.默認的情況下mq服務器端創建隊列和交換機都是持久化的
    2.如果是代碼創建的話,將該值設置爲durablet

10.Rabbitmq發佈訂閱的實現原理
    核心思想:
        一個生產者投遞消息,可以被多個不同的隊列實現消費;
    實現原理:
        多個不同的隊列綁定相同交換機,生產者只需要將消息投遞到交換機之後,
        在由交換機將消息轉發到所有綁定的隊列實現消費。    
        
11.Direct exchange(直連<路由>交換機)
     Fanout exchange(扇型<廣播>交換機)
     Topic exchange(主題交換機)
  交換機核心作用:分發路由消息、中專
    隊列:容器存放多個不同消息 遵循先進先出的原則
    消息:傳遞的參數
    路由鍵:交換機根據這樣的路由鍵的值,發送不同的隊列中 匹配過程
    扇型交換機主要的特徵:只要隊列綁定同一個交換機,生產者將消息投遞到交換機中,交換機會將消息發送給所有綁定的隊列進行存放消息。
    Direct exchange(直連交換機):根據生產者投遞不同的路由鍵,在交換機發送到隊列實現匹配路郵件
    Topic 主題交換機:根據路郵鍵的key實現模糊匹配到隊列存放。    

12.    RabbitMQ如果產生了消息堆積如何處理
    產生的背景:如果沒有及時的消費者消費消息,生產者一直不斷往隊列服務器存放消息
        會導致消息堆積
    兩種場景:
        1.沒有消費者消費的情況下: 死信隊列、設置消息有效期
              相當於對我們的消息設置有效期,在規定的時間內如果沒有消費的話,自動過期,
              過期的時候會執行客戶端回調監聽的方法將消息存放到數據庫記錄,後期實現不補償。

        2.有一個消費者消費的情況:應該提高我們的消費者 消費實現集羣    
        
13.    RabbitMQ如何徹底保證我們的消息不丟失
    1.MQ服務器端應該消息持久化到硬盤
    2.生產者使用消息確認機制百分能夠將消息投遞到MQ成功
    3.消費者使用手動acm機制確認消息百分百消費成功
    如果隊列容量滿了,在繼續投遞可能會丟失 死信隊列
    死信隊列:稱做爲備胎隊列,消息中間件隊列因爲某種消費拒絕存放該消息,可以轉移到死信隊列中存放。
    死信隊列產生的背景
        1.生產者投遞消息到MQ中,消息過期了,轉入死信隊列;
        2.隊列的已經達到最大長度(隊列存放消息滿了)MQ拒絕接受存放該消息。
        3.消費者多次消費該消息失敗的情況,也會存放死信。
    死信隊列不能夠和正常隊列存放在同一個服務器中,應該分開服務器存放

14.訂單30分鐘未支付,系統自動超時關閉有哪些實現方案?
    1.基於任務調度實現,效率是非常低,耗服務器性能
    2.基於redis過期key實現.用戶下單的時候,生成一個令牌(有效期)30分鐘,存放到我們redis;
        redis.set(orderToken ,orderID) 下單時候存放到redis,並存儲id入庫,30分鐘過期,
        redis客戶端監聽,過期獲取到orderId,拿orderId去查訂單,沒有支付則,訂單關閉,庫存增加
        缺點:非常冗餘 ,會在表中存放一個冗餘字段
    3.基於MQ的延遲隊列實現(最佳)    死信隊列
        原理:當我們在下單的時候,往MQ投遞一個消息設置有效期爲30分鐘,但該消息失效的時候(沒有被消費的情況下),
             執行我們客戶端一個方法告訴我們該消息已經失效,這時候查詢這筆訂單是否有支付.
        具體步驟:下單投放消息到A交換機(過期時間30分鐘),消息到aa隊列(綁定死信交換機),不設置aa隊列的消費者.
                 30分鐘後,過期消息投遞到死信交換機,死信隊列,又死信消費者消費,判斷訂單id
                 時候支付,支付->return  未支付->關閉訂單,返還庫存

    4.redis的延遲隊列  https://blog.csdn.net/zhangshengqiang168/article/details/100130523

15.RabbitMQ自動補償機制觸發:(多用於調用第三方接口)
    1.當我們的消費者在處理我們的消息的時候,程序拋出異常情況下(默認無限次數重試)
    2.應該對我們的消息重試設置間隔重試時間,比如消費失敗最多隻能重試5次,間隔3秒(防止重複消費,冪等問題)
    
16.如果重試5次,也就是15秒內重試還是失敗情況下應該如何處理?
    1.默認情況下,重試多次還是失敗的話,會自動刪除該消息(消息可能會丟失)
     解決思路:
      A:如果重試多次還是失敗的情況下,最終存放到死信隊列.
      B:採用表日誌記錄,消費失敗錯誤的日誌記錄 後期人工自動對消息實現補償.

17.分佈式事務產生的背景?
    1.RPC通訊中每個服務都有自己獨立的數據源,每個數據源都互不影響.
    2.在單個項目中存在多個不同jdbc連接(多數據源)
    
18.如何基於我們的MQ解決我們的分佈式事務的問題(最終一致性)
    1.確保我們的生產者往我們的MQ投遞消息一定要成功.(生產者消息確認機制confirm),實現重試.
    2.確保我們的消費者能夠消費成功(手動ack機制),如果消費失敗情況下,MQ自動幫消費者重試.
    3.確保我們的生產者第一事務先執行成功,如果執行失敗採用補單隊列.
          

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章