redis简单:消息队列-高并发-超抢/卖 一边 lpush() 另一边 rpop()。
redis簡單:消息隊列-高并發(fā)-超搶/賣
一邊 lpush() 另一邊 rpop()。
、消息隊列
什么是消息隊列?
是一個消息的鏈表,是一個異步處理的數(shù)據(jù)處理引擎。
用途有哪些?
郵件發(fā)送、手機短信發(fā)送,數(shù)據(jù)表單提交、圖片生成、視頻轉(zhuǎn)換、日志儲存等。
有什么好處?
不僅能夠提高系統(tǒng)的負荷,還能夠改善因網(wǎng)絡(luò)阻塞導(dǎo)致的數(shù)據(jù)缺失。
有哪些軟件?
ZeroMQ、Posix、SquirrelMQ、Redis、QDBM、Tokyo Tyrant、HTTPSQS等(linux平臺下)。
怎么實現(xiàn)?
顧名思義,先入隊,后出隊;先把數(shù)據(jù)丟到消息隊列(入隊),后根據(jù)相應(yīng)的key來獲取數(shù)據(jù)(出隊)。
首先,redis設(shè)計用來做緩存的,但是由于它自身的某種特性使得它可以用來做消息隊列,它有幾個阻塞式的API可以使用,正是這些阻塞式的API讓其有能力做消息隊列;另外,做消息隊列的其他特性例如FIFO(先入先出)也很容易實現(xiàn),只需要一個list對象從頭取數(shù)據(jù),從尾部塞數(shù)據(jù)即可;redis能做消息隊列還得益于其list對象blpop brpop接口以及Pub/Sub(發(fā)布/訂閱)的某些接口,它們都是阻塞版的,所以可以用來做消息隊列。
簡單的代碼實例:
二、redis簡單并發(fā)處理
這里模擬下10000用戶處理
這段代碼解決瞬間處理10000個用戶同時操作數(shù)據(jù)庫,我們就可以在redis中獲取到成功用戶的id,只對這100個用戶做相應(yīng)的操作,
上面的情況正常情況下會有列表中只會存100個用戶,但實際情況中不是while循環(huán),而是多用戶同時訪問這樣的代碼:
在高并發(fā)的情況下,在使用jmeter工具模擬用戶并發(fā)請求時總會發(fā)現(xiàn)多出幾個用戶,也就是出現(xiàn)超賣/超搶,問題代碼:
在搶購進行到一定程度,假如現(xiàn)在已經(jīng)有99個人搶購成功,又來了3個用戶同時搶購,這時if條件將會被繞過(條件同時被滿足了),這三個用戶都能搶購成功。而實際上只剩下一件庫存可以搶了。
在高并發(fā)下,很多看似不大可能是問題的,都成了實際產(chǎn)生的問題了。要解決“超搶/超賣”的問題,核心在于保證檢查庫存時的操作是依次執(zhí)行的,再形象的說就是把“多線程”轉(zhuǎn)成“單線程”。即使有很多用戶同時到達,也是一個個檢查并給與搶購資格,一旦庫存搶盡,后面的用戶就無法繼續(xù)了。
比如這里我先把庫存(可用庫存,這里我強調(diào)下哈,一般都是商品詳情頁搶購,后來者進來看到的庫存可能不再是后臺系統(tǒng)配置的10個庫存數(shù)了)放入redis隊列:
搶購開始
接下來處理list中的user就可以了,上面只是簡單模擬高并發(fā)下的搶購思路,真是場景會比這復(fù)雜多
再如上面的會導(dǎo)致一個用戶搶多個,思路:
需要一個排隊隊列(比如:queue:1,以user_id為值的列表)和搶購結(jié)果隊列(比如:order:1,以user_id為值的列表)及庫存隊列(比如上面的goods_store:1)。高并發(fā)情況,先將用戶進入排隊隊列,用一個線程循環(huán)處理從排隊隊列取出一個用戶,判斷用戶是否已在搶購結(jié)果隊列,如果在則已搶購,否則未搶購,接著執(zhí)行庫存減1,寫入數(shù)據(jù)庫,將此user_id用戶同時也進入結(jié)果隊列。
總結(jié)
以上是生活随笔為你收集整理的redis简单:消息队列-高并发-超抢/卖 一边 lpush() 另一边 rpop()。的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 流水线生产、AI配音的电影解说:正在让几
- 下一篇: docx4j 下载地址