ActiveMQ的延遲和定時投遞

在介紹ActiveMQ的延遲和定時投遞之前,這裏我們先來回顧下在併發編程中介紹的堵塞隊列(二)—— DelayQueue實現限時訂單,其中我們就提到了一個運行場景,即網上購物下單未支付,等支付時間到了之後的處理,最簡單的方式肯定就是輪詢數據庫了,但是輪詢數據庫的話肯定有很多的缺點,如造成數據庫壓力過大,訂單會存在一定的延時情況。


然後爲了避免上述的缺點,我們使用了DelayQueue實現限時訂單,就很好的避免了上述最主要的兩個缺點,那麼使用DelayQueue就不存在缺點了麼,肯定也是有的,如應用重啓怎麼辦啊,DelayQueue中的訂單信息都是存儲在內存中的,如果應用重啓那麼內存中的數據肯定就丟失了,這裏我們就必須在應用重啓的時候取掃一遍數據庫,將未支付已過期的訂單進行處理,然後再進未支付未過期的訂單再次加入DelayQueue,不過這裏的過期時間需要做出相應的處理。


另外除了應用重啓,還存在擴展性的問題,隨着我們的業務逐漸的增大,訂單系統可能會進行集羣化,那麼DelayQueue來處理限時訂單會存在問題麼,肯定也是有的,還是上述的問題,就是在集羣化的情況下,如果應用重啓了,每個服務讀取數據庫掃描一遍,這裏每個服務都會把所有的訂單都拉到自己的DelayQueue隊列中,這樣就會造成重複處理(如果是非冪等的操作就會出現問題)。


上述我們又該如何解決呢?我們就必須給每個訂單加上機器碼,來標註它是屬於哪個服務來處理的,如ip地址等,這樣服務重啓時,每個服務就只去取屬於自己處理的訂單,但是這樣的話,要是其中一臺服務宕機的話,那麼屬於該服務的訂單就不會被處理了,這裏我們就需要去數據庫中該服務訂單的機器碼進行修改,讓其他服務來代替進行處理。




看完上述的過程,是不是發現存在很多的問題,並且處理還挺麻煩,最後甚至還需要去手動修改訂單信息,讓其他服務進行處理,這裏我們能不能使用ActiveMQ來解決呢?


肯定是可以的,我們可以在ActiveMQ來啓動延遲和定時投遞,首先我們需要在ActiveMQ的配置文件acttivemq.xml中,進行相關的配置,在<broker>中加上schedulerSupport="true",以用來增加延遲和定時投遞支持,如下:
在這裏插入圖片描述


然後我們在代碼中發送消息的時候,就需要額外的添加一些描述消息定時調度方式的參數,如下:
在這裏插入圖片描述

在消息發送端只需上述即可(當然還有更多的時間調度方式),其餘操作和之前一樣,然後消費者也不需要進行修改,不過這裏我們爲了看效果,將接受時間大約出來,結果如下:
在這裏插入圖片描述
在這裏插入圖片描述


那麼除了上述我們實現的延遲消息,那麼還有哪幾種調度方式呢,如下:

  • AMQ_SCHEDULED_DELAY: 延遲投遞的時間
  • AMQ_SCHEDULED_PERIOD: 重複投遞的時間間隔
  • AMQ_SCHEDULED_REPEAT: 重複投遞次數
  • AMQ_SCHEDULED_CRON: Cron表達式

如上述我們只是簡單的延遲5秒後進行投遞,這裏我們就還可以進行復雜點的設置,如我們將上述消息不僅延遲5秒,在重複發送一次,間隔時間爲10秒,如下:
在這裏插入圖片描述
在這裏插入圖片描述


可能你認爲上述太過於麻煩,或者有着更爲複雜的調度策略,那麼我們還可以使用Cron表達式來進行設置,可以設置以秒、分鐘、天等單位進行循環,或者進行定時進行投遞,其方式也比較簡單,如下:
在這裏插入圖片描述

CRON和其餘的也是可以一起使用的,如是上,每一分鐘執行一次,會進行重發一次,然後啓動後,我們還可以進入ActiveMQ的控制檯進行查看,如下:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章