redis簡單:消息隊列-高並發-超搶/賣 一邊 lpush() 另一邊 rpop()。


redis簡單:消息隊列-高並發-超搶/賣
一邊 lpush() 另一邊 rpop()。
、消息隊列
什么是消息隊列?
是一個消息的鏈表,是一個異步處理的數據處理引擎。
用途有哪些?
郵件發送、手機短信發送,數據表單提交、圖片生成、視頻轉換、日志儲存等。
有什么好處?
不僅能夠提高系統的負荷,還能夠改善因網絡阻塞導致的數據缺失。
有哪些軟件?
ZeroMQ、Posix、SquirrelMQ、Redis、QDBM、Tokyo Tyrant、HTTPSQS等(linux平台下)。
怎么實現?
顧名思義,先入隊,后出隊;先把數據丟到消息隊列(入隊),后根據相應的key來獲取數據(出隊)。
首先,redis設計用來做緩存的,但是由於它自身的某種特性使得它可以用來做消息隊列,它有幾個阻塞式的API可以使用,正是這些阻塞式的API讓其有能力做消息隊列;另外,做消息隊列的其他特性例如FIFO(先入先出)也很容易實現,只需要一個list對象從頭取數據,從尾部塞數據即可;redis能做消息隊列還得益於其list對象blpop brpop接口以及Pub/Sub(發布/訂閱)的某些接口,它們都是阻塞版的,所以可以用來做消息隊列。

簡單的代碼實例:

二、redis簡單並發處理
這里模擬下10000用戶處理

這段代碼解決瞬間處理10000個用戶同時操作數據庫,我們就可以在redis中獲取到成功用戶的id,只對這100個用戶做相應的操作,
上面的情況正常情況下會有列表中只會存100個用戶,但實際情況中不是while循環,而是多用戶同時訪問這樣的代碼:

在高並發的情況下,在使用jmeter工具模擬用戶並發請求時總會發現多出幾個用戶,也就是出現超賣/超搶,問題代碼:

在搶購進行到一定程度,假如現在已經有99個人搶購成功,又來了3個用戶同時搶購,這時if條件將會被繞過(條件同時被滿足了),這三個用戶都能搶購成功。而實際上只剩下一件庫存可以搶了。
在高並發下,很多看似不大可能是問題的,都成了實際產生的問題了。要解決“超搶/超賣”的問題,核心在於保證檢查庫存時的操作是依次執行的,再形象的說就是把“多線程”轉成“單線程”。即使有很多用戶同時到達,也是一個個檢查並給與搶購資格,一旦庫存搶盡,后面的用戶就無法繼續了。
比如這里我先把庫存(可用庫存,這里我強調下哈,一般都是商品詳情頁搶購,后來者進來看到的庫存可能不再是后台系統配置的10個庫存數了)放入redis隊列:

搶購開始

接下來處理list中的user就可以了,上面只是簡單模擬高並發下的搶購思路,真是場景會比這復雜多
再如上面的會導致一個用戶搶多個,思路:
需要一個排隊隊列(比如:queue:1,以user_id為值的列表)和搶購結果隊列(比如:order:1,以user_id為值的列表)及庫存隊列(比如上面的goods_store:1)。高並發情況,先將用戶進入排隊隊列,用一個線程循環處理從排隊隊列取出一個用戶,判斷用戶是否已在搶購結果隊列,如果在則已搶購,否則未搶購,接着執行庫存減1,寫入數據庫,將此user_id用戶同時也進入結果隊列。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM