1. 程式人生 > >redis簡單:訊息佇列-高併發-超搶/賣

redis簡單:訊息佇列-高併發-超搶/賣

一、訊息佇列
什麼是訊息佇列?
是一個訊息的 連結串列,是一個非同步處理的資料處理引擎。
用途有哪些?
郵件傳送、手機簡訊傳送,資料表單提交、圖片生成、視訊轉換、日誌儲存等。
有什麼好處?
不僅能夠提高系統的負荷,還能夠改善因網路阻塞導致的資料缺失。
有哪些軟體?
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使用者同時也進入結果佇列。
 可以關注部落格園交流問題:https://www.cnblogs.com/emmmmmm/ 

                                                                    -----生生的筆記