最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

RabbitMQ消息隊列實現(xiàn)延遲任務示例

 更新時間:2022年04月02日 16:51:09   作者:Java知識圖譜  
這篇文章主要為大家介紹了RabbitMQ消息隊列實現(xiàn)延遲任務示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪

一、序言

延遲任務應用廣泛,延遲任務典型應用場景有訂單超時自動取消;支付回調(diào)重試。其中訂單超時取消具有冪等性屬性,無需考慮重復消費問題;支付回調(diào)重試需要考慮重復消費問題。

延遲任務具有如下特點:在未來的某個時間點執(zhí)行;一般僅執(zhí)行一次。

1、實現(xiàn)原理

生產(chǎn)者將帶有延遲信息的消息發(fā)送到RabbitMQ交換機中,等待延遲時間結束方將消息轉(zhuǎn)發(fā)到綁定的隊列中,消費者通過監(jiān)聽隊列消費消息。延遲任務的關鍵在消息在交換機中停留。

顯而易見,基于RabbitMQ實現(xiàn)延遲任務對服務器的可靠性要求極高,交換機內(nèi)部消息無持久化機制,比如單機模式服務重啟,未開始的延遲任務均丟失。

2、組件選型

二、方案設計

(一)服務器

RabbitMQ服務需要安裝x-delayed-message插件以處理延遲消息。

(二)生產(chǎn)者

延遲任務的實現(xiàn)對生產(chǎn)者的要求是將消息可靠的投遞到交換機,因此使用confirm確認機制即可。

訂單生成之后,先入庫,然后以訂單ID為key將訂單詳情存入Redis中(持久化),向RabbitMQ發(fā)送異步confirm確定請求。如果收到正常投遞返回,則刪除Redis中訂單ID為key的數(shù)據(jù),回收內(nèi)存,否則以訂單ID為key,從Redis中查詢出訂單數(shù)據(jù),重新發(fā)送。

(三)消費者

延遲任務的實現(xiàn)對消費者的要求是以信息不丟失的方式消費消息,具體表現(xiàn)在:手動確認消息的消費,防止消息丟失;消費端持續(xù)穩(wěn)定,防止消息堆積;消息消費失敗有重試機制。

考慮到訂單延遲取消屬于冪等性操作,因此無需考慮消息的重復消費問題。

三、SpringBoot實現(xiàn)

實現(xiàn)部分僅貼一部分核心源碼,完整項目請訪問GitHub。

(一)生產(chǎn)者

考慮到下單是極為重要的操作,因此首先將訂單落庫、存盤,然后進行后續(xù)操作。

for (long i = 1; i <= 10; i++) {
    /* 1.模擬生成訂單 */
    BuOrder order = createOrder(i);
    /* 2.訂單入庫 */
    orderService.removeById(order);
    orderService.saveOrUpdate(order);
    /* 3.將訂單存入信息Redis */
    RedisUtils.setObject(RabbitTemplateConfig.ORDER_PREFIX + i, order);
    /* 4.向RabbitMQ異步投遞消息 */
    rabbitTemplate.convertAndSend(RabbitmqConfig.DELAY_EXCHANGE_NAME, RabbitmqConfig.DELAY_KEY, order, RabbitUtils.setDelay(30000), RabbitUtils.correlationData(order.getOrderId()));
}

生產(chǎn)者可靠投遞消息

public void confirm(CorrelationData correlationData, boolean ack, String cause) {
    if (correlationData == null) {
        return;
    }
    String key = ORDER_PREFIX + correlationData.getId();
    if (ack) {
        /* 如果消息投遞成功,則刪除Redis中訂單數(shù)據(jù),回收內(nèi)存 */
        RedisUtils.deleteObject(key);
    } else {
        /* 從Redis中讀取訂單數(shù)據(jù),重新投遞 */
        BuOrder order = RedisUtils.getObject(key, BuOrder.class);
        /* 重新投遞消息 */
        rabbitTemplate.convertAndSend(RabbitmqConfig.DELAY_EXCHANGE_NAME, RabbitmqConfig.DELAY_KEY, order, RabbitUtils.setDelay(30000), RabbitUtils.correlationData(order.getOrderId()));
    }
}

(二)消費者

消費者端手動確認,避免消息丟失;失敗自動重試。

@RabbitListener(queues = RabbitmqConfig.DELAY_QUEUE_NAME)
public void consumeNode01(Channel channel, Message message, BuOrder order) throws IOException {
    if (Objects.equals(0, order.getOrderStatus())) {
        /* 修改訂單狀態(tài),設置為關閉狀態(tài) */
        orderService.updateById(new BuOrder(order.getOrderId(), -1));
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        log.info(String.format("消費者節(jié)點01消費編號為【%s】的消息", order.getOrderId()));
    }
}

消費者可靠消費應至少開啟兩個及以上應用,確保消息隊列中不積壓消息。

(三)通用工具包

上述代碼涉及一個工具類RabbitUtils,存在于如下依賴中,主要封裝RabbitMQ極常用的工具方法。

<dependency>
  <groupId>xin.altitude.cms</groupId>
  <artifactId>ucode-cms-common</artifactId>
  <version>1.4.3.1</version>
</dependency>

以上就是RabbitMQ消息隊列實現(xiàn)延遲任務示例的詳細內(nèi)容,更多關于RabbitMQ消息隊列延遲任務的資料請關注腳本之家其它相關文章!

相關文章

  • Java如何實現(xiàn)上傳文件到服務器指定目錄

    Java如何實現(xiàn)上傳文件到服務器指定目錄

    這篇文章主要介紹了Java如何實現(xiàn)上傳文件到服務器指定目錄,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • 使用SpringMVC的@Validated注解驗證的實現(xiàn)

    使用SpringMVC的@Validated注解驗證的實現(xiàn)

    這篇文章主要介紹了使用SpringMVC的@Validated注解驗證的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • java中實現(xiàn)創(chuàng)建目錄與創(chuàng)建文件的操作實例

    java中實現(xiàn)創(chuàng)建目錄與創(chuàng)建文件的操作實例

    用Java創(chuàng)建文件或目錄非常簡單,下面這篇文章主要給大家介紹了關于java中實現(xiàn)創(chuàng)建目錄與創(chuàng)建文件的操作實例,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • 如何在springMVC的controller中獲取request

    如何在springMVC的controller中獲取request

    這篇文章主要介紹了如何在springMVC的controller中獲取request,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • Spring?AI集成DeepSeek實現(xiàn)流式輸出的操作方法

    Spring?AI集成DeepSeek實現(xiàn)流式輸出的操作方法

    本文介紹了如何在SpringBoot中使用Sse(Server-SentEvents)技術實現(xiàn)流式輸出,后端使用SpringMVC中的SseEmitter對象,前端使用EventSource對象監(jiān)聽SSE接口并展示數(shù)據(jù)流,通過這種方式可以提升用戶體驗,避免大模型響應速度慢的問題,感興趣的朋友一起看看吧
    2025-03-03
  • junit4教程junit4.5官方下載

    junit4教程junit4.5官方下載

    前提:本文假設讀者已經(jīng)具有使用JUnit 4以前版本的經(jīng)驗。
    2008-09-09
  • Java之String、StringBuffer、StringBuilder的區(qū)別分析

    Java之String、StringBuffer、StringBuilder的區(qū)別分析

    今天搞安卓在看書的時候遇到了StringBuilder這個類型的東東,有點小迷,不知道它跟string、stringbuffer的關系式怎么樣的,趕快查閱相關資料,了解了個大概,拿出來分享一下
    2012-11-11
  • C++ 歸并排序(merge sort)案例詳解

    C++ 歸并排序(merge sort)案例詳解

    這篇文章主要介紹了C++ 歸并排序(merge sort)案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java中的static關鍵字用法總結

    Java中的static關鍵字用法總結

    這篇文章主要介紹了Java中的static關鍵字用法總結,static是Java50個關鍵字之一,static關鍵字可以用來修飾代碼塊表示靜態(tài)代碼塊,修飾成員變量表示全局靜態(tài)成員變量,修飾方法表示靜態(tài)方法,需要的朋友可以參考下
    2023-11-11
  • Java中的強制類型轉(zhuǎn)換 大數(shù)轉(zhuǎn)小數(shù)

    Java中的強制類型轉(zhuǎn)換 大數(shù)轉(zhuǎn)小數(shù)

    這里主要討論一下大數(shù)轉(zhuǎn)小數(shù),比如int類型轉(zhuǎn)short類型。小數(shù)轉(zhuǎn)大數(shù),如short 轉(zhuǎn) int不做討論,需要的朋友可以參考下
    2020-02-02

最新評論

舟山市| 泰州市| 诏安县| 乡宁县| 寿光市| 运城市| 土默特右旗| 嘉荫县| 西城区| 芒康县| 静安区| 阳原县| 红原县| 正蓝旗| 什邡市| 新民市| 白沙| 彭州市| 平原县| 维西| 博野县| 松溪县| 青龙| 正阳县| 中西区| 井冈山市| 通州区| 集安市| 东平县| 沂南县| 平阴县| 远安县| 宝丰县| 凤阳县| 钟祥市| 富阳市| 白城市| 晋州市| 波密县| 绥阳县| 渭南市|