1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        延時(shí)任務(wù)實(shí)現(xiàn)方案

        共 395字,需瀏覽 1分鐘

         ·

        2021-12-25 07:46

        業(yè)務(wù)場景

        我們買火車票或者叫外賣的時(shí)候,下完單之后會跳轉(zhuǎn)到支付頁面,頁面里通常會有一個(gè)計(jì)時(shí)器,要求在指定時(shí)間內(nèi)完成支付,否則訂單就會被自動取消。這就是延時(shí)任務(wù)的一個(gè)典型業(yè)務(wù)場景。分析這個(gè)場景,其實(shí)最關(guān)鍵的就是如何在訂單超時(shí)的時(shí)候立即觸發(fā)取消訂單的動作。

        那么如何實(shí)現(xiàn)這種延時(shí)業(yè)務(wù)呢?通常有以下4種方案。

        定時(shí)任務(wù)輪詢db

        用戶下單后db中會生成一條訂單記錄,記錄了訂單號、用戶ID、創(chuàng)建時(shí)間、訂單詳情、訂單狀態(tài)等信息。假設(shè)超時(shí)時(shí)間是600秒,我們后臺起一個(gè)定時(shí)任務(wù),每隔固定時(shí)間運(yùn)行一次,每次掃描db中的超時(shí)訂單select * from order where createTime <= now()-600,然后取消查詢到的訂單。

        這種方法實(shí)現(xiàn)簡單,但是有很多缺點(diǎn)。超時(shí)時(shí)間通常是秒級的,如果定時(shí)任務(wù)每秒運(yùn)行一次,那么就相當(dāng)于每秒就要對訂單表做一次掃描,這是相當(dāng)消耗db資源的操作,因此定時(shí)任務(wù)一般不會設(shè)置為秒級;但是如果設(shè)置為分鐘級,又會犧牲即時(shí)性,比如600秒超時(shí),很有可能660秒的時(shí)候訂單才被取消。

        DelayQueue

        JDK的DelayQueue(延遲隊(duì)列)是無界阻塞隊(duì)列,只有在延遲期滿時(shí)才能從中獲取元素。每生成一個(gè)訂單,在把訂單記錄到db的同時(shí),要把訂單id等信息投遞到延遲隊(duì)列中去,隊(duì)列會按照超時(shí)時(shí)間進(jìn)行排序,最先超時(shí)的訂單排在隊(duì)列的頭部;起一個(gè)單獨(dú)的線程不斷地從隊(duì)列中摘取元素然后去做取消訂單的動作。

        這種方法最大的缺點(diǎn)就是沒有將超時(shí)信息持久化,服務(wù)重啟之后延遲隊(duì)列的元素不會被恢復(fù)。

        redis的zset

        在redis中創(chuàng)建一個(gè)key是”delayOrders”的zset,每個(gè)member就是訂單ID,member的score就是該訂單的超時(shí)時(shí)間戳。我們每次從zset中取出score最小也就是最先超時(shí)的元素,判斷其是否超時(shí),如果超時(shí)就將其從zset中刪除并取消訂單,如果未超時(shí)就繼續(xù)執(zhí)行下一次循環(huán)。

        RabbitMQ的TTL+DLX

        RabbitMQ可設(shè)置消息過期時(shí)間(TTL),當(dāng)消息過期后可以將該消息投遞到隊(duì)列上設(shè)置的死信交換器(DLX)上。然后投遞到死信隊(duì)列中,重新消費(fèi)。

        四種方案對比

        方案優(yōu)點(diǎn)缺點(diǎn)
        定時(shí)任務(wù)輪詢db實(shí)現(xiàn)簡單、無技術(shù)難點(diǎn)、異?;謴?fù)、支持分布式/集群環(huán)境影響數(shù)據(jù)庫性能、時(shí)效性差
        DelayQueue實(shí)現(xiàn)簡單、性能較好無法異?;謴?fù)、分布式/集群實(shí)現(xiàn)困難
        redis的zset解耦、異?;謴?fù)、擴(kuò)展性強(qiáng)、支持分布式/集群環(huán)境增加redis維護(hù)、占用帶寬
        RabbitMQ的TTL+DLX解耦、異?;謴?fù)、擴(kuò)展性強(qiáng)、支持分布式/集群環(huán)境增加RabbitMQ維護(hù)、占用帶寬


        source: //xiangxianzui.github.io/2020/02/延時(shí)任務(wù)實(shí)現(xiàn)方案

        喜歡,在看

        瀏覽 36
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲成人性爱视频 | 男女无码视频 | 成人Av音影 | 亚洲噜噜噜噜噜噜 | 成人午夜福利在线 | 欧美性猛交XX乱大交 | 亚洲午夜精品久久久久久久久久久久 | 国产精品久久久久久久久久不蜜月 | 国产黄色全禁视频网 | 少妇xxxxx性开放 |