文章目錄
- 1.RabbitMQ 核心組件及功能詳解
- 2.RabbitMQ-如何保證消息不丟失?
- 3.RabbitMQ消息的重復消費問題如何解決的?
- 4.RabbitMQ中死信交換機 ? (RabbitMQ延遲隊列有了解過嘛)
- 5.RabbitMQ如果有100萬消息堆積在MQ , 如何解決(消息堆積怎么解決)
- 6.RabbitMQ的高可用機制有了解過嘛
- 7.RabbitMQ如何保證消息的有序性?
- 8.RabbitMQ有哪些消息處理模式(訂閱模式或工作模式)?
1.RabbitMQ 核心組件及功能詳解
RabbitMQ 核心組件及功能詳解
2.RabbitMQ-如何保證消息不丟失?
消息中間件的好處
- 提供了系統之間的異步調用,讓服務與服務之間解耦
- 削峰、填谷
場景:
- 異步發送(驗證碼、短信、郵件…)
- MySQL和Redis , ES之間的數據同步
- 分布式事務
- 削峰填谷
消息發送者(publisher )把消息發送給交換機(exchange),由交換機路由到隊列,最后由消費者(consumer)進行消費消息。
出現消息丟失的四種情況:
- 消息未到達交換機
- 消息未到達隊列
- 隊列中消息丟失
- 消費者未接收到消息
生產者確認機制(解決消息未到達交換機、消息未到達隊列問題)
RabbitMQ提供了publisher confirm機制來避免消息發送到MQ過程中丟失。消息發送到MQ以后,會返回一個結果(ack)給發送者,表示消息是否處理成功
如果消息發送失敗,有兩種情況:
- 消息到達交換機失敗(publisher-confirm nack)
- 交換機路由到隊列失敗(publisher-return ack)
消息失敗之后如何處理呢?
- 回調方法即時重發(知道哪一個消息發送失敗,可以再發)
- 記錄日志(如果還是發送失敗,可以記錄日志,通過查看日志進行補償)
- 保存到數據庫然后定時重發,成功發送后即刻刪除表中的數據
如果重發失敗了怎么辦?
- 一般消息發送失敗了,很大幾率是服務提供者宕機了或者是MQ宕機了,這兩者不可能一直處于宕機狀態。
- 如果還是不能解決,需要人工來解決這些問題
消息已經正常發送到隊列,但是MQ 宕機了,也會導致消息丟失,該怎么解決?
消息持久化(解決隊列中消息丟失問題)
MQ默認是內存存儲消息,開啟持久化功能可以確保緩存在MQ中的消息不丟失。(MQ宕機或重啟后,在內存中的消息肯定會丟失,需要持久化)
1.交換機持久化:
@Bean
public DirectExchange simpleExchange(){
// 三個參數:交換機名稱、是否持久化、當沒有queue與其綁定時是否自動刪除
return new DirectExchange("simple.direct", true, false);
}
2.隊列持久化:
@Bean
public Queue simpleQueue(){
// 使用QueueBuilder構建隊列,durable就是持久化的
return QueueBuilder.durable("simple.queue").build();
}
3.消息持久化,SpringAMQP中的的消息默認是持久的,可以通過MessageProperties中的DeliveryMode來指定的:
Message msg = MessageBuilder
.withBody(message.getBytes(StandardCharsets.UTF_8)) //消息體
.setDeliveryMode(MessageDeliveryMode.PERSISTENT) //持久化
.build()