環境:JDK7以上。git
源碼根目錄有ppt文檔。redis
本文方案是看了58的一位架構師的分享,但並無實現細節。本文是對方案的深刻研究及代碼實現數據庫
:exclamation: 業務場景網絡
1.下單以後若是三十分鐘以內或12小時沒有付款就自動取消訂單架構
2.下單成功後60s以後給用戶發送短信通知併發
3.用戶但願經過手機遠程遙控家裏的智能設備在指定的時間進行工做。這時候就能夠將用戶指令發送到延時隊列,當指令設定的時間到了再將指令推送到只能設備。 4.七天自動收貨分佈式
5.必定時間後自動評價高併發
6.業務執行失敗以後隔10分鐘重試一次性能
…….測試
本質都是過一段時間後才執行任務
下單成功後60s以後給用戶發送短信通知爲例。
:exclamation: 方案一: 定時掃描表
實現:啓動一個定時任務,每分鐘查一次數據庫表,把下單成功超過60秒而且沒有發太短信通知的的取出來,而後去處理。
缺點: 1.若是數據量很大,查表輪詢效率就低。 2.每分鐘輪詢一次增長了數據庫壓力。 3.若是是增大輪詢時間間隔,那麼時效性(準確性)又下降了
:exclamation: 方案二: redis
實現:經過zset機構模擬,定時器去讀zset數據去處理。
不足:
1.數據量大,一zset性能有問題。 固然能夠多定義幾個zset,再數據量大的時候分散到不一樣zset裏面,但存和定時器去讀的複雜性增長了。 2.消息處理失敗是不能被恢復。也有考慮過將分爲TODO和Doing兩條隊列。可是因爲Redis的事務特性,並不能作到徹底可靠;而且檢查Doing超時的邏輯也略複雜 並非成熟方案,須要本身去實現。
:exclamation: 方案三: JAVA DelayQueue
實現:DelayQueue自己就是延遲隊列
不足:
1.經過先將消息排序再定時觸發的方式來實現延遲消息。因此大量消息時,性能不能保證 2.想提供必定可靠性(如數據持久性),擴展性不方便 3.分佈式須要額外實現
:exclamation: 方案四: MQ
實現:老版本的MQ大多沒有延時隊列的實現。 不過如今新版本慢慢有了延時投遞的功能。 如:ActiveMQ 能夠延時投遞,但有人測試在往隊列中投遞大量(10w+)定時消息以後,ActiveMQ的性能將會變得接近不可用,大量的消息擠壓得不到投遞,可多機。 RocketMQ 支持定時消息,可是不支持任意時間精度,支持特定的level,例如定時5s,10s,1m等。 RabbitMQ 經過他的一些特性也能夠模擬出延遲隊列的功能,或者有一些第三方插件
完善的MQ系統可實現一個高可靠的分佈式延遲消息隊列。仍在發展中,但尚未徹底比較專用的延遲消息功能
:exclamation: 方案五: 本身實現延時MQ 有能力能夠作,mq實現起來仍是耗費資源的
:+1: 方案六: 本身實現延時隊列
咱們本身實現輕量級的延時隊列。
初級版本目標: 網絡或down機容許消息丟失。即業務完整性不保證 支持高併發 不提供客戶端 只作一個內嵌的jar,不單獨作一個成品應用服務
具體見: https://gitee.com/itman666/wheel-timer-queue/wikis/Home