RabbitMq 學習記錄 持續更新~~~~

 
    RabbitMq學習:
        
        1.概念:rabbitMq是基於amqp的高級協議,運行速度和socket一致。
        
        2.核心組件:
              broker:服務器(server)
              exchange:
                   1.direct:直接匹配
                   2.topic:模糊匹配
                        #:關鍵字後面多詞模糊匹配
                        *: 關鍵字後面只匹配一個詞
                        通常是消費者這邊使用通配符的匹配生產者
                   3.fanout:不需要處理路由件,不走任何的路由key,會將消息發送到指定交換機的指定queue上。
                            性能最好,因爲不走路由
                   
              channel:通道,所有操作都在通道完成
              message: 由兩部分組成:properties(消息設置)、body(具體內容)
              queue:
              routingkey:
              virtual host:虛擬地址,用於邏輯隔離,最上層的消息路由。同一個virtual host中不能夠有相同名字的exchange或者queue
                             
        3.提供者和消費者
            提供者:只關心exchange和routingKey
            消費者:只關心queue和routingKey以及exchange0
            
            如果消息提供者沒有指定exchange的話,就會默認使用AMQP DEFAULT exchange 根據routingKey去完全匹配一個queue,
            如果能夠匹配就將消息路由出去,否則刪除message。
            
            
        4.消息可靠性投遞方案
           
            1.消息入庫機制,在發送消息之前,將消息入庫並這隻狀態爲發送中。消息正常發送到rabbit server並返回confirm,將數據庫消息發送狀態爲完成。設置分佈式任務等待server的confirm返回值,如果在規定的時間沒有返回值則重新retry 發送消息。在規定的次數內完成發送並收到server的confirm返回值,將數據庫狀態設置爲完成。如在規定的次數未完成,則將數據庫消息發送狀態設置爲失敗。後期全部發送完畢之後統一處理(日誌信息顯示失敗原因!rpc調用會出現網絡原因)
            
            2.延遲發送:消息提供者首先入庫消息的部分信息,同時起連個發送服務,一個立即發送,一個延時發送(具體延時時間看具體情況)新建一個callback listener監聽消費者端發送回來的confirm messge以及提供者延時發送的消息,如果能夠監聽到,則將這條信息入庫。如果不能夠監聽到則提示提供者重新發送信息。當延時發送的消息被監聽到,回去數據庫中查詢是否要這條消息的消費記錄,如果有則不運行這條延時發送的消息,如果在規定的時間中依然沒有這條消息的消費記錄,則消費延時消息。
              
        5.如何避免消息的重複消費?
           
            使用消息提供者端的comfirm listener來監聽消息返回值。
            
            返回值爲ack or noack
        
        6.如何判斷消息提供者提供的消息是否被消費?
        
            使用return listener來監聽消息是否被消費。
            
        7.自定義consumer extends DedfaultConsumer就能夠實現消費了。
        
        8.消費端的限流處理方式:
        
            爲什麼要進行消費端限流?
                巨量的消息推送過來,單個客戶端無法同時處理這些海量的數據,可能會導致客戶端宕機,故需要進行消費端限流配置。RabbitMq提供了一種qos功能,在非自動確認消息的前提下,如果一定數目的消息未被確認前,不進行消費新的消息

            原生api:defaultConsumer.basicqos(int perfetchSize,int perfetchCount,bollean gloal)
            
            perfetchSize: 0 表示不指定上限,其他的數字表示指定上限。
            
            perfetchCount:表示客戶端(消費者端)能夠同時接收的最大消息數量
            
            gloal: true 便是針對整個channel,faalse針對的是 consumer
        
        注意事項:要想使用qos進行限流,必須將ack設置爲手動ack
        
        Demo:
        
           /**
         *  聲明一個exchange
         */
        channel.exchangeDeclare(exchangeName,exchangeType,true);
        /**
         *  聲明一個隊列
         */
        channel.queueDeclare(queueName,true,false,false,null);
        channel.queueBind(queueName,exchangeName,routingKey);
        /**   指定提供者的數量    指定同時過來多少條,其餘的要等到這些ack後再過來  

                 是否全局化true針對channel false consumer
         *    int prefetchSize, int prefetchCount,  boolean global
         */
        channel.basicQos(0,3,false);
        DefaultConsumer consumer = new MyConsumer(channel);
        /**
         * String queue, boolean autoAck, Consumer callback
         */
        channel.basicConsume(queueName,false,consumer);

        
        
        9.ack和手動ack
            
            ack是消費者是否成功消費消息的標識,其中關鍵配置參數爲:Boolean autoAck true = 自動ack false=手動ack
            
            provider可以用 confirm listener來監聽消息是否被消費,同時給出相關處理。
            
            手動ack需要在自定義的消費者中,直接根據某個條件來判斷其是否ack。
              basicAck() 爲成功消費消息!
              basicNack() 手動消費失敗!
              
        10.死信隊列 dlx dead letter exchange
        
            什麼情況下消息會進入死信隊列?
            
             1.消息沒有被成功消費,同時在手動nack處理時參數requeue被設置爲false,這時候消息會進入死信隊列。
             2.消息時間過期,TTL過期,超過設置的最大消息存活時間。
             3.超過設置qos中的最大隊列數:perftchSize
             
            死信隊列的聲明:在消費端聲明,和其他的交換機聲明方式一致。死信隊列數據存放在隊列裏面。
            
            
        11.自定義adpter中必須實現一個默認方法名:handleMessage
        
        
        12.springboot 註解接收消息:
        
            @RabbitHandler
            @RabbitListener(指定queue、指定exchange、指定routingkey)
            
            onmessage(@Payload  目標屬性 @Headers  需要的屬性內容)
            
            從properties裏面讀取數據只需要使用${springboot.rabbitMq.exchange.name} 表達式形式處理就ok了
            
            
        13.集羣的恢復。
        
            1.正常的A、B(b爲master)關閉停機。
                先啓動A,30s後啓動B。或者先啓動B再啓動A即可。
                
            2.A B同時停機(機房掉電等原因)。
                只需要在30s內啓動A B兩個節點即可。
                
            3.A(備用節點)掛了,B(主節點)沒有掛。
                啓動B(主節點),然後再主節點上執行rabbitmqctl forget_cluster-node-A 解除A節點和本集羣的關係,然後再新啓動一個節點作爲從(備)節點加入到該集羣即可
            
            4.A(備用節點)沒掛,B(主)節點掛掉了。
                先啓動A節點,然後再A節點上啓動命令:rabbitmqctl forget_cluster-node-B_offline 就可以在主節點不在線的情況下解除主節點和該集羣的綁定,然後再將A作爲主節點,最後新啓動一個新的節點作爲從節點加入該集羣即可。
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
        
            
        

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