基於Redis實現的延遲隊列

delay-queue

基於Redis實現的延遲隊列, 參考有贊延遲隊列設計實現git

項目地址github

應用場景

  • 訂單超過30分鐘未支付,自動關閉數據庫

  • 訂單完成後, 若是用戶一直未評價, 5天后自動好評json

  • 會員到期前15天, 到期前3天分別發送短信提醒異步

猜測

支付寶異步通知時間間隔是如何實現的(通知的間隔頻率通常是:2m,10m,10m,1h,2h,6h,15h) ui

訂單支付成功後, 生成通知任務, 放入消息隊列中.
任務內容包含Array{0,0,2m,10m,10m,1h,2h,6h,15h}和通知到第幾回N(這裏N=1, 即第1次).
消費者從隊列中取出任務, 根據N取得對應的時間間隔爲0, 當即發送通知. 設計

第1次通知失敗, N += 1 => 2
從Array中取得間隔時間爲2m, 添加一個延遲時間爲2m的任務到延遲隊列, 任務內容仍包含Array和N code

第2次通知失敗, N += 1 => 3, 取出對應的間隔時間10m, 添加一個任務到延遲隊列, 同上
......
第7次通知失敗, N += 1 => 8, 取出對應的間隔時間15h, 添加一個任務到延遲隊列, 同上
第8次通知失敗, N += 1 => 9, 取不到間隔時間, 結束通知接口

實現原理

利用Redis的有序集合,member爲JobId, score爲任務執行的時間戳,隊列

每秒掃描一次集合,取出執行時間小於等於當前時間的任務.

依賴

  • Redis

運行

./delay-queue -c delay-queue.conf

HTTP Server監聽0.0.0.0:9277, Redis鏈接地址127.0.0.1:6379, 數據庫編號1

HTTP接口

  • 請求方法 POST

  • 請求Body及返回值均爲json

返回值

{
  "code": 0,
  "message": "添加成功",
  "data": null
}
參數名 類型 含義 備註
code int 狀態碼 0: 成功 非0: 失敗
message string 狀態描述信息
data object, null 附加信息

添加任務

URL地址 /push

{
  "topic": "order",
  "id": "15702398321",
  "delay": 3600,
  "ttr": 120,
  "body": "{\"uid\": 10829378,\"created\": 1498657365 }"
}
參數名 類型 含義 備註
topic string Job類型
id string Job惟一標識 需確保JobID惟一
delay int Job須要延遲的時間, 單位:秒
ttr int Job執行超時時間, 單位:秒
body string Job的內容,供消費者作具體的業務處理,若是是json格式需轉義

輪詢隊列獲取任務

服務端會Hold住鏈接, 直到隊列中有任務或180秒後超時返回,
任務執行完成後需調用finish接口刪除任務, 不然任務會重複投遞, 消費端需能處理同一任務的屢次投遞

URL地址 /pop

{
  "topic": "order"
}
參數名 類型 含義 備註
topic string Job類型

隊列中有任務返回值

{
  "code": 0,
  "message": "操做成功",
  "data": {
    "id": "15702398321",
    "body": "{\"uid\": 10829378,\"created\": 1498657365 }"
  }
}

隊列爲空返回值

{
  "code": 0,
  "message": "操做成功",
  "data": null
}

刪除任務

URL地址 /delete

{
  "id": "15702398321"
}
參數名 類型 含義 備註
id string Job惟一標識

完成任務

URL地址 /finish

{
  "id": "15702398321"
}
參數名 類型 含義 備註
id string Job惟一標識
相關文章
相關標籤/搜索