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