【CouponHub項目開發】使用RocketMQ5.x實現延時修改優惠券狀態,并通過使用模板方法模式重構消息隊列發送功能

在上個章節中我實現了創建優惠券模板的功能,但是,優惠券總會有過期時間,我們怎么去解決到期自動修改優惠券狀態這樣一個功能呢?我們可以使用RocketMQ5.x新出的任意定時發送消息功能來解決。

初始方案:
在這里插入圖片描述

  • 首先在創建優惠券模板下面繼續添加代碼。首先先創建topic
    在這里插入圖片描述
  • 接著去定義消息體
// 執行 RocketMQ5.x 消息隊列發送&異常處理邏輯SendResult sendResult;try {sendResult = rocketMQTemplate.syncSendDeliverTimeMills(couponTemplateDelayCloseTopic, message, deliverTimeStamp);log.info("[生產者] 優惠券模板延時關閉 - 發送結果:{},消息ID:{},消息Keys:{}", sendResult.getSendStatus(), sendResult.getMsgId(), messageKeys);} catch (Exception ex) {log.error("[生產者] 優惠券模板延時關閉 - 消息發送失敗,消息體:{}", couponTemplateDO.getId(), ex);}
  • 接著去調用相關方法去發送消息

這樣一個延時發送的消息生產者就定義好了,接著我們去定義消費者。

在這里插入圖片描述

  • 我們可以創建一個消費者類讓他去實現RocketMQListener然后添加 @RocketMQMessageListener 注解,其中加上 Topic 和消費者組定義
  • 接著我們可以在onMessage方法內去定義我們接收到消息以后需要去做什么
  • 這里我們需要去修改數據庫當中的優惠券的狀態

這樣就已經解決了定時修改優惠券模板狀態這樣的功能,但是這樣直接寫在代碼當中不是太優雅,而且耦合度太高。我們可以通過去定義一個生產者的抽象類(模板),然后去通過定義具體的類來繼承這些抽象類。然后在創建優惠券模板的方法中我們只需要去定義一個事件,然后調用該類的方法去發送消息即可。

@RequiredArgsConstructor
@Slf4j(topic = "CommonSendProduceTemplate")
public abstract class AbstractCommonSendProduceTemplate<T> {private final RocketMQTemplate rocketMQTemplate;/*** 構建消息發送事件基礎擴充屬性實體** @param messageSendEvent 消息發送事件* @return 擴充屬性實體*/protected abstract BaseSendExtendDTO buildBaseSendExtendParam(T messageSendEvent);/*** 構建消息基本參數,請求頭、Keys...** @param messageSendEvent 消息發送事件* @param requestParam     擴充屬性實體* @return 消息基本參數*/protected abstract Message<?> buildMessage(T messageSendEvent, BaseSendExtendDTO requestParam);/*** 消息事件通用發送** @param messageSendEvent 消息發送事件* @return 消息發送返回結果*/public SendResult sendMessage(T messageSendEvent) {BaseSendExtendDTO baseSendExtendDTO = buildBaseSendExtendParam(messageSendEvent);SendResult sendResult;try {// 構建 Topic 目標落點 formats: `topicName:tags`StringBuilder destinationBuilder = StrUtil.builder().append(baseSendExtendDTO.getTopic());if (StrUtil.isNotBlank(baseSendExtendDTO.getTag())) {destinationBuilder.append(":").append(baseSendExtendDTO.getTag());}// 延遲時間不為空,發送任意延遲消息,否則發送普通消息if (baseSendExtendDTO.getDelayTime() != null) {sendResult = rocketMQTemplate.syncSendDeliverTimeMills(destinationBuilder.toString(),buildMessage(messageSendEvent, baseSendExtendDTO),baseSendExtendDTO.getDelayTime());} else {sendResult = rocketMQTemplate.syncSend(destinationBuilder.toString(),buildMessage(messageSendEvent, baseSendExtendDTO),baseSendExtendDTO.getSentTimeout());}log.info("[生產者] {} - 發送結果:{},消息ID:{},消息Keys:{}", baseSendExtendDTO.getEventName(), sendResult.getSendStatus(), sendResult.getMsgId(), baseSendExtendDTO.getKeys());} catch (Throwable ex) {log.error("[生產者] {} - 消息發送失敗,消息體:{}", baseSendExtendDTO.getEventName(), JSON.toJSONString(messageSendEvent), ex);throw ex;}return sendResult;}
}

在該抽象類中定義了兩個抽象方法,

  • protected abstract BaseSendExtendDTO buildBaseSendExtendParam(T messageSendEvent);該方法用來補充事件的相關屬性

  • protected abstract Message<?> buildMessage(T messageSendEvent, BaseSendExtendDTO requestParam);該方法是用來補充消息的屬性

  • sendMessage方法中首先會通過buildBaseSendExtendParam方法把事件的屬性進行補充,比如延時時間等。

  • 然后會獲取這個時間是否存在延時時間這個屬性,如果有則發送延時消息,如果沒有,就發送普通消息。

在這里插入圖片描述
這就是延時發送消息的生產者的一個實現類

在這里插入圖片描述
這是消費者沒有太大變化。

我們現在梳理一下它的執行流程

  • 創建完優惠券模板之后,我們根據優惠券的相關信息構建出一個發送事件templateDelayEvent
  • 然后通過自動注入的couponTemplateDelayExecuteStatusProducer延時發送消息的生產者,調用它的發送消息方法進行延時發送消息。
  • 這個生產者是去實現了生產者的一個抽象類,并實現了補充事件屬性,以及構建消息體的抽象方法。
  • 然后消費者通過監聽該消息來完成消費。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95400.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95400.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95400.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Claude Code SDK 配置Gitlab MCP服務

一、MCP配置前期準備 &#xff08;一&#xff09;創建個人令牌/群組令牌 我這里是創建個人令牌&#xff0c;去到首頁左上角&#xff0c;點擊頭像——>偏好設置——>訪問令牌——>添加新令牌 &#xff08;二&#xff09;配置mcp信息 去到魔塔社區&#xff0c;點擊mc…

Eclipse 常用搜索功能匯總

Eclipse 常用搜索功能匯總 Eclipse 提供了多種搜索功能&#xff0c;幫助開發者快速定位代碼、文件、類、方法、API 等資源。以下是詳細的使用方法和技巧。 一、常用搜索快捷鍵快捷鍵功能描述Ctrl H打開全局搜索對話框&#xff0c;支持文件、Java 代碼、任務等多種搜索。Ctrl …

關于Spring的一些理解

Spring整體結構&#xff1a;Spring實際運行場景&#xff1a;基礎 Spring啟動過程 傳統Spring&#xff1a; &#xff08;1&#xff09;初始化準備階段 &#xff08;2&#xff09;容器創建與注入 &#xff08;3&#xff09;Bean工廠后置處理 &#xff08;4&#xff09;Bean工廠后…

Windows右下角系統托盤圖標快速顯示或隱藏

系統托盤指的是Windows電腦桌面右下角的區域&#xff0c;包括時間、wifi&#xff08;網絡&#xff09;、音量、電源、輸入法、一些程序/應用等。啟動了應用后&#xff0c;Windows會把部分應用的圖標顯示或隱藏在系統托盤區。我們可以根據需要快速顯示或隱藏相關應用&#xff0c…

Kotlin編程學習記錄2

Kotlin編程學習記錄2——條件與循環 條件語句&#xff1a;if 與 when ? Kotlin 的控制流把“表達式優先”作為設計原則——if、when 不只是控制語句&#xff0c;都可以作為表達式使用并返回值&#xff0c;這影響了日常代碼風格&#xff08;更函數式、可組合&#xff09;。筆…

印度物聯網崛起:政策紅利下的千億藍海與本土化博弈

印度物聯網市場正處于快速發展階段,2025年市場規模預計達到200億美元,主要得益于政府"數字印度"計劃和智能城市項目的推動。蜂窩物聯網連接數在2024年同比增長34%,2025年Q1增速進一步提升至32%,其中智能電表部署和資產追蹤應用成為核心驅動力。然而,市場也面臨著…

html學習:

ok,今天準備學一下html&#xff0c;花費點時間整理一下&#xff1a; HTML標簽的語法格式 HTML 中的標簽就像關鍵字一樣&#xff0c;每個標簽都有自己的語義&#xff08;含義&#xff09;。 HTML 標簽的語法格式 屬性↓ <div class"begin">cyx</div>↑…

CRYPT32!PkiAsn1Decode函數分析的一個例子

第一部分&#xff1a; 0: kd> g Breakpoint 35 hit CRYPT32!PkiAsn1Decode: 001b:75c9af0c 55 push ebp 1: kd> kc# 00 CRYPT32!PkiAsn1Decode 01 CRYPT32!PkiAsn1DecodeAndAllocInfo 02 CRYPT32!PkiAsn1DecodeAndAllocInfoEx 03 CRYPT32!Asn1InfoDecode…

大模型蒸餾、大模型微調、RAG

前言&#xff1a; 有很多同學想學習大模型開發&#xff0c;又無從下手&#xff0c;網上一搜&#xff0c;鋪天蓋地的付費課程。又不想當韭菜&#xff0c;打破認知障礙&#xff0c;通過自學&#xff0c;改變自己&#xff0c;改變世界&#xff01; 一、大模型蒸餾、微調、RAG的適…

25高教社杯數模國賽【E題保姆級思路+問題分析】

注&#xff1a;本內容由”數模加油站“ 原創出品&#xff0c;雖無償分享&#xff0c;但創作不易。 歡迎參考teach&#xff0c;但請勿抄襲、盜賣或商用。 E 題 AI輔助智能體測 《國家學生體質健康標準》的頒布&#xff0c;有效地促進了大中小學生關注自身體質健康的發展&#xf…

基于單片機車內換氣溫度檢測空氣質量檢測系統Proteus仿真(含全部資料)

全套資料包含&#xff1a;Proteus仿真源文件keil C語言源程序AD原理圖流程圖元器件清單說明書等 資料下載&#xff1a; 通過網盤分享的文件&#xff1a;資料分享 鏈接: 百度網盤 請輸入提取碼 提取碼: tgnu 目錄 資料下載&#xff1a; Proteus仿真功能 項目文件資料&#…

MySQL子查詢的分類講解與實戰

精選專欄鏈接 &#x1f517; MySQL技術筆記專欄Redis技術筆記專欄大模型搭建專欄Python學習筆記專欄深度學習算法專欄 歡迎訂閱&#xff0c;點贊&#xff0b;關注&#xff0c;每日精進1%&#xff0c;與百萬開發者共攀技術珠峰 更多內容持續更新中&#xff01;希望能給大家帶來…

Leetcode 206. 反轉鏈表 迭代/遞歸

原題鏈接&#xff1a;Leetcode 206. 反轉鏈表 解法一&#xff1a;迭代 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* …

C++11新特性 | 歡迎來到現代C++的世界!

左值與右值 左值與右值的概念 可以被取地址的值為左值&#xff08;left value&#xff0c;簡稱lvalue&#xff09;&#xff0c;否則為右值&#xff08;right value&#xff0c;簡稱rvalue&#xff09;。 常見的左值、右值例子&#xff1a; // >>>>>>> 左值…

因為對象裝箱拆箱導致的空指針異常

今天業務突然提了個事件單&#xff0c;客戶添加承租人一直報錯&#xff0c;但是很奇怪&#xff0c;報錯信息是空的二話不說&#xff0c;先跟API組要了接口和參數&#xff0c;然后看日志然鵝&#xff0c;這個接口并沒有打印日志&#xff0c;只有一個e.printStackTrace()然后靜下…

Rust 在 Windows 環境下交叉編譯其他操作系統可執行文件的詳細指南

前言&#xff1a;為什么需要交叉編譯&#xff1f; 想象一下這樣的場景&#xff1a;你在 Windows 電腦上開發了一個 Rust 程序&#xff0c;希望它能在 Linux 服務器上運行&#xff0c;或者在朋友的 macOS 電腦上測試 —— 總不能為了編譯不同系統的版本&#xff0c;專門買一臺 …

Ubuntu系統配置鏡像源

要修改的文件 /etc/apt/sources.list操作步驟 1. 備份原文件 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak2. 編輯文件 sudo nano /etc/apt/sources.list3. 清空文件內容&#xff0c;填入以下內容 先獲取Ubuntu版本代號&#xff1a; lsb_release -cs然后根據版本填…

【Spring Cloud Alibaba】Sentinel(一)

【Spring Cloud Alibaba】Sentinel&#xff08;一&#xff09;1. 簡介2. 服務雪崩1. 簡介 Sentinel 是阿里巴巴開源的分布式系統的流量防護組件&#xff0c;主要用來做流量控制、熔斷降級、系統保護。它的定位類似于 Hystrix&#xff0c;但更側重在 流量治理 上。目前在微服務…

Delphi 5 操作Word表格選區問題解析

在 Delphi 5 中操作 Word 時&#xff0c;您遇到的 Selection.MoveDown 方法選中整行而不是僅移動一行的原因與 Word 的選擇機制和單元格內部結構有關。以下是詳細解釋和解決方案&#xff1a;問題分析單元格的選區范圍&#xff1a;當使用 .Cell(r, c).Select 選中單元格時&#…