Springboot2.2.6構建RabbitMQ消息異常處理

2020-12-11 萬裡山川

接續之前文章

Springboot2.2.6構建RabbitMQ消息接收端代碼

Springboot2.2.6構建RabbitMQ消息發布端代碼

大家好,我是技術人小Top

今天咱們來介紹如何使用RabbitMQ構建消息異常處理 ^-^

RabbitMQ官網:www.rabbitmq.com

上次介紹了Spring2.26如何構建RabbitMQ消息接收端

具體到應用開發,需要使用RabbitMQ API來實現具體業務場景

現在開始進入實戰

01消息是否落地保存

建議:落地保存

1、落地保存的好處

消息保存在資料庫中方便人工和程序處理雖然RabbitMQ具備消息持久化的特性,但是它畢竟不是存儲設備。相比較資料庫而言,數據的可讀性、易用性和穩定性都要遜色。

事後方便業務對帳通常消息發送和接收確認後,RabbitMQ中不再持久化消息了。這時一旦業務對帳出現了問題,消息不存在則無法追溯,無法對異常情況進行復位排差。

2、落地保存的具體位置/時機

詳見本文開頭的文章

發送消息到Exchange成功時發送消息到Exchange失敗時發送消息到Queue失敗時接收消息成功時接收消息失敗時

02消息是否設置過期

根據實際需要來決定

1、設置過期時間的好處

消息及時釋放/刪除會減輕RabbitMQ對磁碟佔用的壓力從業務角度來說,消息的持久化畢竟是短暫的或瞬態的,不需要像資料庫那樣永久保存數據

即使出現異常也不會對RabbitMQ造成磁碟壓力只要配合消息落地,就算有異常產生,在設計層面可以依賴資料庫保證數據的永久可追溯

2、設置過期時間的實現

對Queue或Message都可設置過期時間大多數場景會對Queue設置過期時間

當同時設置過期時間時,以最小的過期時間為準

03消息是否設置死信隊列

根據實際需要來決定

1、設置死信隊列的好處

保證消費的隊列沒有垃圾數據由於通常消息是持久化的,原隊列也就是業務隊列中的數據會不斷進入新的消息。這時如果存在異常消息(也就是消費端處理過程中發生異常而無法處理)長時間存放在原隊列是沒有意義的。因為這通常需要消費端排查問題並修復代碼。

保證消費的隊列高效運行由於沒有死信(處理不了的異常消息),隊列消費的速度會很高效。反之,如果重複入隊,效率會降低。如果不重複入隊,需要有追溯機制來跟進和解決異常問題。

便於保存異常消息並定位問題2、設置死信隊列的實現

之前的AMQP協議、模型及RabbitMQ常用組件文章中發過這樣一張圖,說明了AMQP的工作原理

在此圖基礎上,我們把死信交換機和死信隊列加上,一張圖就能看明白了(請關注紅色箭頭)

1、當Consumer1Queue(user1)中接收消息失敗時,調用API告訴RabbitMQ拋棄錯誤消息

2、由於Queue(user1)設置了死信交換機,被拋棄的消息成為死信進入死信交換機user1DLXExchange

3、由於Queue(user1DLX)綁定了死信交換機,死信隊列會接收到被拋棄的消息

我們將之前文章中的代碼稍加改造就可以了

04小結

今天主要介紹了如何構建RabbitMQ異常處理

小夥伴們都了解了嗎?

下次小Top將繼續介紹RabbitMQ開發

對於今天的內容有任何疑問或問題,歡迎留言或討論 ^-^

05本文涉及的代碼

/**

* 死信交換機user1名稱

*/

public static final String MQ_DLX_EXCHANGE_USER1 = "user1DLXExchange";

/**

* 死信交換機user2名稱

*/

public static final String MQ_DLX_EXCHANGE_USER2 = "user2DLXExchange";

/**

* 死信隊列user1名稱

*/

public static final String MQ_DLX_QUEUE_USER1 = "user1DLX";

/**

* 死信隊列user2名稱

*/

public static final String MQ_DLX_QUEUE_USER2 = "user2DLX";

@Bean

public Declarables declarables() {

//Todo: user1指定死信交換機deadLetterExchange

Queue userQueue1 = QueueBuilder

.durable(MQ_QUEUE_USER1)

.deadLetterExchange(MQ_DLX_EXCHANGE_USER1)

.build();

//Todo: user2指定死信交換機deadLetterExchange

Queue userQueue2 = QueueBuilder

.durable(MQ_QUEUE_USER2)

.deadLetterExchange(MQ_DLX_EXCHANGE_USER2)

.build();

FanoutExchange fanoutExchange = ExchangeBuilder.

fanoutExchange(MQ_FANOUT_EXCHANGE_USER)

.durable(true)

.build();

DirectExchange directExchange = ExchangeBuilder

.directExchange(MQ_FANOUT_EXCHANGE_TEST)

.durable(true)

.build();

//Todo: 定義死信隊列

Queue userDLXQueue1 = QueueBuilder

.durable(MQ_DLX_QUEUE_USER1)

.ttl(300000)

.build();

Queue userDLXQueue2 = QueueBuilder

.durable(MQ_DLX_QUEUE_USER2)

.ttl(300000)

.build();

//Todo: 定義死信隊列交換機

FanoutExchange dlxUser1Exchange = ExchangeBuilder

.fanoutExchange(MQ_DLX_EXCHANGE_USER1)

.durable(true)

.build();

FanoutExchange dlxUser2Exchange = ExchangeBuilder

.fanoutExchange(MQ_DLX_EXCHANGE_USER2)

.durable(true)

.build();

return new Declarables(userQueue1, userQueue2, fanoutExchange, directExchange,

userDLXQueue1, userDLXQueue2, dlxUser1Exchange, dlxUser2Exchange,

BindingBuilder.bind(userQueue1).to(fanoutExchange),

BindingBuilder.bind(userQueue2).to(fanoutExchange),

BindingBuilder.bind(userDLXQueue1).to(dlxUser1Exchange),

BindingBuilder.bind(userDLXQueue2).to(dlxUser2Exchange));

}

相關焦點

  • Springboot2.2.6構建RabbitMQ消息發布端代碼
    接續之前文章AMQP協議、模型及RabbitMQ常用組件消息中間件RabbitMQ、微服務,以及數據一致性問題消息中間件RabbitMQ,為什麼使用RabbitMQ以及它支持的場景大家好,我是技術人小Top今天咱們來介紹如何使用RabbitMQ構建消息發布端 ^-^
  • 詳解SpringCloud中RabbitMQ消息隊列原理及配置,一篇就夠!
    rabbitmq已經被spring-boot做了整合訪問實現。spring cloud也對springboot做了整合邏輯。所以rabbitmq的依賴可以在spring cloud中直接使用。如果在消息處理過程中,消費者的伺服器在處理消息時發生異常,那麼這條正在處理的消息就很可能沒有完成消息的消費,如果RabbitMQ在Consumer消費消息後立刻刪除消息,則可能造成數據丟失。為了保證數據的可靠性,RabbitMQ引入了消息確認機制。
  • 基於Spring Boot 2.2.6實現Rest風格的文件上傳&下載APIs-附源碼
    基於Spring Boot 2.0實戰系列源碼已經Push到Github倉庫:https://github.com/ramostear/springboot2.0-action 。感興趣的朋友歡迎Star/Fork。1.
  • Spring Boot 2.4 手工和 SDKMAN! 安裝 Spring Boot 命令行
    可用的下載地址,請參考下面的連結:spring-boot-cli-2.4.2-SNAPSHOT-bin.zipspring-boot-cli-2.4.2-SNAPSHOT-bin.tar.gzSapshot 版本下載,snapshot 版本的意思是從最新的原始碼庫中進行編譯構建的,通常這個版本具有更多的 Bug 修復,下載地址請訪問下面的連結: snapshot 構建版本
  • Spring Boot Admin 2.2.4 發布,兼容最新版本 Spring Boot
    spring boot admin 2.2.4 版本發布,本版本為 bug 修復版本 主要兼容 spring boot 2.3.x。
  • spring-boot-plus V1.2.3 發布,新增 CentOS 相關腳本
    [V1.2.3-RELEASE] 2019.09.09 💻spring-boot-plusV1.2.3發布,CentOS快速安裝環境/構建/部署/啟動項目⭐️ New Features
  • 如何使用Spring Boot與RabbitMQ結合實現延遲隊列
    如下圖所示,消費者發現該消息處理出現了異常,比如是因為網絡波動引起的異常。那麼如果不等待一段時間,直接就重試的話,很可能會導致在這期間內一直無法成功,造成一定的資源浪費。那麼我們可以將其先放在緩衝隊列中(圖中紅色隊列),等消息經過一段的延遲時間後再次進入實際消費隊列中(圖中藍色隊列),此時由於已經過了「較長」的時間了,異常的一些波動通常已經恢復,這些消息可以被正常地消費。
  • Spring Boot 2.X 實戰--SQL 資料庫(MyBatis)
    Gradle 依賴 1dependencies { 2    implementation 'org.springframework.boot:spring-boot-starter-web' 3    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter
  • 消息隊列:Rabbitmq如何保證不丟消息
    用於提交事務,txRollback用於回滾事務,在通過txSelect開啟事務之後,我們便可以發布消息給broker代理伺服器了,如果txCommit提交成功了,則消息一定到達了broker了,如果在txCommit執行之前broker異常崩潰或者由於其他原因拋出異常,這個時候我們便可以捕獲異常通過txRollback回滾事務了。
  • 基於Spring Boot+Cloud構建微雲架構
    Spring Framework:即通常所說的spring 框架,是一個開源的Java/Java EE全功能棧應用程式框架,其它spring項目如spring boot也依賴於此框架。Spring XD:是一種運行時環境(伺服器軟體,非開發框架),組合spring技術,如spring batch、spring boot、spring data,採集大數據並處理。
  • Spring Boot 常見錯誤及解決方法
    Jar 包啟動不了執行 Spring Boot 構建的 jar 包後,返回 「my.jar 中沒有主清單屬性」 錯誤。錯誤分析: Spring Boot 的正常 jar 包運行方是通過 spring-boot-loader 這個模塊裡的 JarLauncher 完成的,該類內部提供了一套運行的規範。
  • Spring Boot 配置 log4j2
    在配置之前,我們需要知道的是 Log4j2 是 Log4j 的升級版,它在 Log4j 的基礎上做了諸多改進:1.異步日誌;2.支持 Java8 lambda 風格的懶加載日誌;3.過濾器;4.插件;5.並發性改進;6.支持: SLF4J, Commons Logging, Log4j-1.x 以及 java.util.logging
  • Spring Boot 啟動事件和監聽器,太強大了!
    9、ApplicationFailedEvent這個事件在應用啟動異常時進行發送。Spring Boot 基礎的構建這裡就不介紹了,如果你對 Spring Boot 還不是很熟悉,或者只是會簡單的使用,那還是建議你深入學習下吧,推薦這個 Spring Boot 學習倉庫,歡迎 Star 關注:https://github.com/javastacks/spring-boot-best-practice1、新建監聽器
  • Spring Boot集成JDBCTemplate
    conn.close(); } catch (SQLException e1) { e1.printStackTrace(); } } } }}通過上述操作,我們會發現整個操作步驟非常複雜,而且涉及到資料庫驅動加載、建立連結、執行操作、解析結果、資源的關閉、異常處理等多個步驟
  • SpringBoot+RabbitMQ (保證消息100%投遞成功並被消費)
    三、項目介紹springboot版本2.1.5.RELEASE, 舊版本可能有些配置屬性不能使用, 需要以代碼形式進行配置RabbitConfig: rabbitmq相關配置TestServiceImpl: 生產者, 發送消息MailConsumer: 消費者, 消費消息, 發送郵件ResendMsg: 定時任務, 重新投遞發送失敗的消息說明
  • Spring Boot 2.0 Release Notes 中文版
    本版本中一些重要的依賴升級包括:Tomcat 8.5Flyway 5Hibernate 5.2Thymeleaf 3Reactive Spring許多使用Spring構建的項目的現在都在為 reactive applications提供一流的支持。響應式編程是完全異步和非阻塞的。
  • Spring Boot 和 Spring 到底有啥區別?
    2)嵌入式Tomcat、Jetty、 Undertow容器(無需部署war文件)。6)完全沒有代碼生成和XML配置要求。Web應用程式:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.6.RELEASE<
  • 2021 最新版 Spring Boot 速記教程
    Demo 腳手架項目地址:https://github.com/Vip-Augus/springboot-noteTable of Contents generated with DocToc@ControllerAdvice 用來處理全局數據構建項目
  • 實戰Spring Boot 2.0系列:單機定時任務的幾種實現
    但是在星期和月中 "L" 表示不同的意思,如:在月子段中 "L" 指月份的最後一天 - 1月31日,2月28日。如果在星期欄位中則簡單的表示為 "7" 或者 "SAT" 字符。如果在星期欄位中在某個 value 值得後面,則表示 "某月的最後一個星期value",如 "6L" 表示某月的最後一個星期五。
  • Spring 和 Spring Boot 之間到底有啥區別?
    2、嵌入式 Tomcat、 Jetty、 Undertow容器(無需部署war文件)。3、提供的 starters 簡化構建配置4、儘可能自動配置 spring應用。><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.0.6.RELEASE</version></dependency