您好,登錄后才能下訂單哦!
RabbitMQ消息丟失問題和保證消息可靠性之消費端不丟消息和HA的示例分析,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
上面兩個操作保證消息到服務端不丟,但是非高可用狀態,如果節點掛掉,服務暫時不可用,需要重啟后,消息恢復,消息不會丟失,因為有磁盤存儲。
本文先從消費端講起:
上面一篇文章也提到了,消費者獲取到消息之后,沒有來得及處理完畢,自己直接宕機了,因為消息者默認采用自動ack,此時RabbitMQ的自動ack機制會通知MQ Server這條消息已經處理好了,此時消息就丟了,并不是預期的。
那么我們采用手動ack機制來解決這個問題,消費端處理完邏輯之后再通知MQ Server,這樣消費者沒處理完消息不會發送ack,如果在消費者拿到消息,沒來得及處理的情況下自己掛了,此時MQ集群會自動感知到,它就會自覺的重發消息給其他的消費者服務實例。
根據上面的思路你需要完成下面的兩步操作:
第一:消費者監聽設置手動ack
this.channel = channelManager.getListenerChannel(namespace); this.queue = queue; this.channel.basicConsume(queue, false, consumerTag, this); this.disconnectedCallback.setChannel(channel);
核心代碼: this.channel.basicConsume(queue, false, consumerTag, this); 第二個參數設置 false 代表不自動ack
第二:業務執行完成后手動ack
public static void ack(MessageContext context) { long deliveryTag = context.getEnvelope().getDeliveryTag(); try { context.getChannel().basicAck(deliveryTag, false); } catch (IOException e) { throw new MqAckException("消息ack出錯:連接異常或遠端關閉", context, e); } }
核心代碼: context.getChannel().basicAck(deliveryTag, false);
這里封裝來,需要業務在執行完自己的業務代碼后,調用對象channel 的ack方法通知MQServer,說我這邊執行完了,你可以刪除了。
注意這里有個問題: 如果忘記調用這個 context.getChannel().basicAck(deliveryTag, false);
或者因為代碼異常,這個代碼沒被執行,會怎么樣?后面找時間再寫一篇文章講這個問題。
當我們解決了,生產端和消費端的問題后,基本保證消息的不丟問題,但是還有一個是消息的高可用問題,單節點問題,普通節點的問題都會影響消息的臨時不可用,這個時候要用上我們的HA 鏡像集群模式來保證。
上一篇文章 解決RabbitMQ消息丟失問題和保證消息可靠性(一) 已經提到過,服務端消息部署的三種模式的區別,今天就專門講鏡像模式的介紹。
鏡像模式至少采用3節點,2個磁盤節點和1個內存節點來保證,架構圖:
設置鏡像也有一些策略:
同步至所有的,一般不這么做,性能會受到極大影響
同步最多N個機器
只同步至符合指定名稱的nodes
> 命令處理HA策略模版:rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
為每個以“rock.wechat”開頭的隊列設置所有節點的鏡像,并且設置為自動同步模式
rabbitmqctl set_policy ha-all "^rock.wechat" '{"ha-mode":"all","ha-sync-mode":"automatic"}' rabbitmqctl set_policy -p rock ha-all "^rock.wechat" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
為每個以“rock.wechat.”開頭的隊列設置兩個節點的鏡像,并且設置為自動同步模式
rabbitmqctl set_policy -p rock ha-exacly "^rock.wechat" \ '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
為每個以“node.”開頭的隊列分配指定的節點做鏡像
rabbitmqctl set_policy ha-nodes "^nodes\." \ '{"ha-mode":"nodes","ha-params":["rabbit@nodeA", "rabbit@nodeB"]}'
> 但是:HA 鏡像隊列有一個很大的缺點就是: 系統的吞吐量會有所下降
所以采用鏡像模式,要根據具體的業務規則定制話處理,沒那么重要的業務,消息丟了也沒關系的場景,又要求必須高的性能的時候,鏡像也可以不用設置。
關于RabbitMQ消息丟失問題和保證消息可靠性之消費端不丟消息和HA的示例分析問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。