Redis如何实现分布式锁

最近事情比较少,随便整理一下之前写的一些可以挪用到其他项目的小功能,之前一个项目接入企业微信加好友的接口,回调的时候存在重复回调的问题,所以加了一个redis锁解决问题:

实现思路与注意事项:

设置合理的过期时间,解决忘记释放锁、甚至服务器宕机未释放锁的问题
获取锁和设置过期时间,需要具有原子性,使用指令

SET key value NX PX milliseconds
NX 代表只有当键key不存在的时候才会设置key的值
PX 表示设置键 key 的过期时间,单位是毫秒
  • value 值随机设置,删除 value 前判断是否相等,解决当前线程可能释放其他线程加的锁的问题
  • lua 脚本可以解决,删除 value 时判断-删除,非原子操作的问题

项目的代码 放在公用目录function.php:

    /**
     * redis 锁
     * @param $cacheKey
     * @return bool
     */
    function set_redis_lock($cacheKey): bool
    {
        $redis = make(Redis::class);
        $result = $redis->setnx($cacheKey, 1);
        $redis->expire($cacheKey, 600);
        return $result;
    }

    /**
     * 删除锁
     * @param $cacheKey
     * @return int
     */
    function del_redis_lock($cacheKey): int
    {
        return make(Redis::class)->del($cacheKey);;
    }

回调业务中的代码示例:

$cacheKey = 'wechatFissionNumber:'.$helpId;
if (!set_redis_lock($cacheKey)) return [];  //如果存在不执行后面的业务处理

try {
     ...里面是不可看内容
} catch (\Throwable $t) {
    wlog($this->logPath, '异常msg:' . $t->getMessage() . PHP_EOL);
    return [];
} finally {
    del_redis_lock($cacheKey);   //处理完业务,释放锁
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容