場景
- 商品庫存
- 兌換碼
操作
- 查庫存
- 秒殺入隊
中間件
- Zookeeper
Leader選舉(單任務(wù)隊列),節(jié)點命名(多任務(wù)隊列) - Redis
單任務(wù)隊列,資源池,庫存計數(shù),已秒殺用戶Mapping
實現(xiàn)方法
- 單任務(wù)隊列
Zk Leader選舉,Redis實現(xiàn)任務(wù)隊列,Redis維護(hù)單個碼池與庫存計數(shù) - 多任務(wù)隊列
Zk節(jié)點命名,Redis維護(hù)各節(jié)點碼池與庫存計數(shù),JVM本地SingleThreadExecutor任務(wù)隊列
秒殺
通過Redis判斷用戶是否已秒殺
判斷并加載庫存
入隊列(bounded,discard policy)
查庫存
判斷并加載庫存
- 單隊列
直接返回Redis庫存計數(shù)
-多隊列
Redis中各計算節(jié)點庫存計數(shù)之和
任務(wù)執(zhí)行
判斷并加載庫存
庫存不足或碼池為空,嘗試加載庫存或碼池(多節(jié)點或redis宕機(jī)場景)
碼池peek兌換碼
begin db transaction
讀節(jié)點庫存或讀兌換碼
庫存不夠或兌換碼已使用或用戶已秒殺,更新redis(庫存=0,刪碼,更新mapping)(樂觀回滾或悲觀鎖),重新入任務(wù)隊列或discard,直接return
更新DB
end db transaction
db事務(wù)成功,Redis更新:
- 用戶秒殺mapping
- 庫存 - 1 or 刪碼
判斷并加載庫存
初始狀態(tài)(Redis宕機(jī)或應(yīng)用首次啟動),中間狀態(tài)(節(jié)點池歸零),終結(jié)狀態(tài)(總池歸零)
初始狀態(tài)和中間狀態(tài)需加載庫存,如加載發(fā)現(xiàn)總池歸零,進(jìn)入終結(jié)狀態(tài)
終結(jié)狀態(tài)秒殺任務(wù)不再入隊列,秒殺結(jié)束
已入隊列任務(wù)直接return