SpringBoot + Redis:類比 10w 人的秒殺搶單!
對於分散式鎖的生成通常需要注意如下幾個方面:
創建鎖的策略: redis的普通key一般都允許覆蓋,A使用者set某個key后,B在set相同的key時同樣能成功,如果是鎖場景,那就無法知道到底是哪個使用者set成功的;這裡jedis的setnx方式為我們解決了這個問題,簡單原理是:當A使用者先set成功了,那B使用者set的時候就返回失敗, 滿足了某個時間點只允許一個使用者拿到鎖。
美國GOOGMAN GOOGMAN增大丸官網 goodman增大丸評價 增大丸 增長增粗
鎖過期時間:某個搶購場景時候,如果沒有過期的概念,當A使用者生成了鎖,但是後面的流程被阻塞了一直無法釋放鎖,那其他使用者此時獲取鎖就會一直失敗,無法完成搶購的活動;當然正常情況一般都不會阻塞,A使用者流程會正常釋放鎖;過期時間只是為了更
這裡注意點在於jedis的set方法,其參數的說明如
setnx如果失敗直接封裝返回false即可,下面我們通過一個get方式的api來調用下這個setnx方法:
訪問如下測試url,正常來說第一次返回了true,第二次返回了false,由於第二次請求的時候redis的key已存在,所以無法se
由上圖能夠到只有一次set成功,並key具有一個有效時間,此時已到達了分散式鎖的條件。
上面是創建鎖,同樣的具有有效時間,但是我們不能完全依賴這個有效時間,場景如:有效時間設置1分鐘,本身使用者A獲取鎖后,沒遇到什麼特殊情況正常生成了搶購訂單后,此時其他用戶應該能正常下單了才對,但是由於有個1分鐘后鎖才能自動釋放,那其他使用者在這1分鐘無法正常下單(因為鎖還是A使用者的),因此我們需要A使用者操作完后,主動去解鎖
增大丸推薦 增大丸效果 增大丸ptt goodman增大丸怎麼吃
這裡也使用了jedis方式,直接執行lua腳本:根據val判斷其是否存在,如果存在就del;
其實個人認為通過jedis的get方式獲取val后,然後再比較value是否是當前持有鎖的使用者,如果是那最後再刪除,效果其實相當;只不過直接通過eval執行腳本,這樣避免多一次操作了redis而已,縮短了原子操作的間隔。 (如有不同見解請留言探討);同樣這裡創建個get方式的api來測試: