redis預減庫存:主要思路減少對資料庫的訪問,之前的減庫存,直接訪問資料庫,讀取庫存,當高併發請求到來的時候,大量的讀取資料有可能會導致資料庫的崩潰。
思路:1.系統初始化的時候,將商品庫存載入到redis 快取中儲存
2.收到請求的時候,現在redis中拿到該商品的庫存值,進行庫存預減,如果減完之後庫存不足,直接返回邏輯exception
就不需要訪問資料庫再去減庫存了,如果庫存值正確,進行下一步
3.將請求入隊,立即給前端返回乙個值,表示正在排隊中,然後進行秒殺邏輯,後端佇列進行秒殺邏輯,前端輪詢後端發來的請求,如果秒殺成功,返回秒殺,成功,不成功就返回失敗。
(後端請求 單執行緒 出隊,生成訂單,減少庫存,走邏輯)前端同時輪詢
4.前端顯示
第一步: 預減庫存
/**
* 秒殺介面優化之--- 第一步: 系統初始化後就將所有商品庫存放入 快取
*/@override
public void afterpropertiesset() throws exception
for (goodsvo goodsvo : goods)
}
/**秒殺介面優化之 ----第二步: 預減庫存 從快取中減庫存
* 利用 redis 中的方法,減去庫存,返回值為 減去1 之後的值
* */
long stock = redisservice.decr(goodskey.getgoodsstock, "" + goodsid);
/*這裡判斷不能小於等於,因為減去之後等於 說明還有是正常範圍*/
if (stock < 0)
1.先將所有資料讀出來,初始化到快取中,並以 stock + goodid 的形成存入redis,
2.在秒殺的時候,先進行預減庫存檢測,從redis中,利用decr 減去對應商品的庫存,如果庫存小於0,說明此時 庫存不足,則不需要訪問資料庫。直接丟擲異常即可
由於介面優化很多基於redis的快取操作,當併發很高的時候,也會給redis伺服器帶來很大的負擔,如果可以減少對redis伺服器的訪問,也可以達到的優化的效果。
於是,可以加乙個記憶體map,標記對應商品的庫存量是否還有,在訪問redis之前,在map中拿到對應商品的庫存量標記,就可以不需要訪問redis 就可以判斷沒有庫存了。
1.生成乙個map,並在初始化的時候,將所有商品的id為鍵,標記false 存入map中。
private mapisovermap = new hashmap();
/*** 秒殺介面優化之--- 第一步: 系統初始化後就將所有商品庫存放入 快取
*/@override
public void afterpropertiesset() throws exception
for (goodsvo goodsvo : goods)
}/**再優化: 優化 庫存之後的請求不訪問redis 通過判斷 對應 map 的值
* */
boolean isover = isovermap.get(goodsid);
if (isover)
if (stock < 0) {
isovermap.put(goodsid, true);//沒有庫存就設定 對應id 商品的map 為true
2.在預減庫存之前,從map中取標記,若標記為false,說明庫存,還有,
3.預減庫存,當遇到庫存不足的時候,將該商品的標記置為true,表示該商品的庫存不足。這樣,下面的所有請求,將被攔截,無需訪問redis進行預減庫存。
介面優化 Redis預減庫存,記憶體標記
redis預減庫存 主要思路是減少對資料庫的訪問,之前的減庫存,直接訪問資料庫,讀取庫存,當高併發請求到來時,大量的讀取資料有可能會導致資料庫的崩潰。秒殺介面優化思路 系統初始化時,將商品庫存載入到redis快取中儲存 收到請求的時候,先在redis中拿到該商品的庫存值,進行庫存預減,如果減完之後庫...
redis預減庫存 rabbitmq非同步下單
減緩存 新增佇列 responsebody domiaosha public resultbean findall requestparam goodsid long goodsid,pathvariable string path,user user,long addresssid throws ...
秒殺場景下mysql減庫存邏輯優化
問題背景 某天早上做活動,流量大量增長,導致大量更新庫存操作失敗。操作mysql返回的錯誤均為 lost connection to mysql server 即mysql服務端主動斷開了連線,導致update操作失敗。都是在sql執行過程中返回的 lost 且都是update操作返回 lost 同...