锁是多线程编程的一个重要功能,它主要用于防止多个线程同时访问一个资源,从而造成资源出问题的情况。
传统的锁是在单机范围之内的,在同一台机器上,如果是分布式应用,则我们必须保证多台机器访问一个资源的串行。这时就需要使用分布式锁来实现。
分布式锁主要有两个步骤组成,获取锁和删除锁,并且这两个步骤必须考虑一下几个条件:
- 原子性:获取锁和删除锁必须满足原子性,即在这两个过程中,不能出现中间失败的情况。
- 超时时间:如果一个客户端获取到锁之后挂掉了,就会造成死锁。因此,需要在获取锁中添加超时时间,在超时时间过了之后,自动释放锁。
- 客户端标识:这是由超时时间引起的,如果没有客户端标识,可能会出现某个超时的进程将其他进程获取到的锁删除的情况。
Laravel 框架的实现方案
<?php
namespace App\Utils;
use Illuminate\Support\Facades\Redis;
class RedisLock
{
public static function lock($key, $requestId, $expire)
{
$res = Redis::command('set', [$key, $requestId,'EX', $expire, 'NX']);
return strtoupper($res) === 'OK';
}
public static function unlock($key, $requestId)
{
$res = Redis::eval("if redis.call('get', KEYS[1]) == KEYS[2] then return redis.call('del', KEYS[1]) else return 0 end", 2, $key, $requestId);
return strtoupper($res) === 'OK';
}
}
参考资料
网友评论