1. redis加鎖分類html
redis能用的的加鎖命令分表是INCR、SETNX、SETredis
2. 第一種鎖命令INCR緩存
這種加鎖的思路是, key 不存在,那麼 key 的值會先被初始化爲 0 ,而後再執行 INCR 操做進行加一。
而後其它用戶在執行 INCR 操做進行加一時,若是返回的數大於 1 ,說明這個鎖正在被使用當中。服務器
一、 客戶端A請求 服務器 獲取key的值爲1表示獲取了鎖 併發
二、 客戶端B也去請求服務器獲取key的值爲2表示獲取鎖失敗ui
三、 客戶端A執行代碼完成,刪除鎖code
四、 客戶端B在等待一段時間後在去請求的時候獲取key的值爲1表示獲取鎖成功server
五、 客戶端B執行代碼完成,刪除鎖htm
$redis->incr($key); $redis->expire($key, $ttl); //設置生成時間爲1秒
3. 第二種鎖SETNX事務
這種加鎖的思路是,若是 key 不存在,將 key 設置爲 value
若是 key 已存在,則 SETNX 不作任何動做
一、 客戶端A請求服務器設置key的值,若是設置成功就表示加鎖成功
二、 客戶端B也去請求服務器設置key的值,若是返回失敗,那麼就表明加鎖失敗
三、 客戶端A執行代碼完成,刪除鎖
四、 客戶端B在等待一段時間後在去請求設置key的值,設置成功
五、 客戶端B執行代碼完成,刪除鎖
$redis->setNX($key, $value); $redis->expire($key, $ttl);
4. 第三種鎖SET
上面兩種方法都有一個問題,會發現,都須要設置 key 過時。那麼爲何要設置key過時呢?若是請求執行由於某些緣由意外退出了,致使建立了鎖可是沒有刪除鎖,那麼這個鎖將一直存在,以致於之後緩存再也得不到更新。因而乎咱們須要給鎖加一個過時時間以防不測。
可是藉助 Expire 來設置就不是原子性操做了。因此還能夠經過事務來確保原子性,可是仍是有些問題,因此官方就引用了另一個,使用 SET 命令自己已經從版本 2.6.12 開始包含了設置過時時間的功能。
一、 客戶端A請求服務器設置key的值,若是設置成功就表示加鎖成功
二、 客戶端B也去請求服務器設置key的值,若是返回失敗,那麼就表明加鎖失敗
三、 客戶端A執行代碼完成,刪除鎖
四、 客戶端B在等待一段時間後在去請求設置key的值,設置成功
五、 客戶端B執行代碼完成,刪除鎖
$redis->set($key, $value, array('nx', 'ex' => $ttl)); //ex表示秒
====================
咱們不用記錄cuid,只要把redis做爲咱們的鎖就行。
客服1和客服2同時接入,
客服1請求鎖成功,則進行接入,接入後刪除鎖,
客服2請求鎖不成功,就一直循環
while 請求鎖不成功:
查找優先級最高的客戶uid
請求鎖,
接入客戶
======================
也可用來限制併發量
https://cloud.tencent.com/developer/article/1376410