redis 使用setnx实现锁

3 篇文章 0 订阅
3 篇文章 0 订阅

在token失效时,要重新请求服务器生成新的token,如果不使用锁的话,在并发的情况下,会有很多请求同时请求服务器。

这里提供一个使用redis来实现锁的。

redis的setnx :当键不存在时插入成功,存在时插入失败。插入成功即拿到锁。

查询资料发现这样一段代码:

<?php

$ok = $redis->set($key, $value, array('nx', 'ex' => $ttl));

if ($ok) {
    $cache->update();
    $redis->del($key);
}
?>

在yii项目中使用之后,提示错误,set() 函数的第三个参数应为string,give array。

最后修改成

$lock = $redis->set('access_token_lock', 1, 'ex', 60, 'nx'); //当键不存在时,设置键和值以及过期时间

参考资料地址:
redis使用命令参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,Redis可以使用setnx命令来实现分布式setnx命令是Redis中的一个原子性操作,用于设置一个键值对,当键不存在时才会设置成功,如果键已经存在则设置失败。我们可以利用这个特性来实现分布式,比如可以将一个键作为名称,将当前时间作为的值,然后使用setnx命令来尝试获取,如果获取成功,则说明获取了,否则说明已经被其他进程占用。 为了避免死,我们还需要给设置过期时间,这样即使某个进程在获取之后发生了意外导致没有及时释放,也不会一直占用资源。 下面是使用setnx命令实现分布式的示例代码: ``` import redis import time class RedisLock: def __init__(self, redis_client, name, expire=60): self.redis_client = redis_client self.name = name self.expire = expire def acquire(self): while True: now = time.time() expires = now + self.expire if self.redis_client.setnx(self.name, expires): return expires else: value = self.redis_client.get(self.name) if value and now > float(value): old_value = self.redis_client.getset(self.name, expires) if old_value and old_value == value: return expires time.sleep(0.1) def release(self): self.redis_client.delete(self.name) ``` 在上面的代码中,我们定义了一个RedisLock类,它的构造函数接收一个Redis客户端对象、名称和过期时间。acquire方法用来获取,如果获取成功则返回的过期时间,否则阻塞等待。release方法用来释放,它会删除的键值对。在acquire方法中,我们不断循环尝试获取,直到获取成功为止。如果获取失败,则检查是否已经过期,如果过期则尝试用getset命令更新的值,并检查更新前后的值是否相等,如果相等则说明获取到了,否则继续重试。为了避免过多的CPU消耗,我们在尝试获取时加上了一个短暂的等待时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值