ezijng/hyperf-redlock

hyperf redis 分布式锁

V1.0.1 2022-07-25 07:48 UTC

This package is auto-updated.

Last update: 2024-09-25 12:35:16 UTC


README

composer require ezijng/hyperf-redlock

基于 redlock-phpHyperf 2.1.* 转换

本sdk基于redlock-php向hyperf ~2.1版本改造。

在使用前建议先了解Redlock算法的原理,请参阅Redis作者Antirez对Redlock算法的解释(英文)

参考基于Redis的分布式锁算法RedLock及RedLock-Hyperf实现

使用

简单使用

    try {
        $lock = $this->container->get(RedLock::class)->setRedisPoolName()->setRetryCount(1)->lock('redlock-hyperf-test', 60000);
        if ($lock) {
            //do your code
            $this->container->get(RedLock::class)->unlock($lock);
        }
    } catch (\Throwable $throwable) {
        var_dump($throwable->getMessage());
    }
  • setRedisPoolName方法用于指定Redlock使用哪些Redis实例作为分布式独立节点,这里需要传入索引数组,默认['default'],数组的值应该是/config/autoload/redis.php下的连接池name。关于为什么要使用独立的Redis节点:

    img.png

  • setRetryCount方法用于设置获取锁的重试次数,默认2次

  • setRetryDelay用于一次获取锁失败后延迟时间后重试,默认200,单位毫秒

  • lock方法,获取锁

    • 参数:resource:锁的key
    • 参数:ttl:锁过期时间,单位毫秒。
    • 返回:array|false
  • unlock方法,释放锁

    • 参数:参数:lock方法成功后的return
  • 如果担心请求保持锁阶段进程出现重启或退出情况,建议增加以下代码

//参考 RedlockHyperf\Aspect\RedLockAspect
if ($lock) {
  //to release lock when server receive exit sign
  Coroutine::create(function () use ($lock) {
  $exited = CoordinatorManager::until(Constants::WORKER_EXIT)->yield($lock['validity']);
  $exited && $this->redlock->unlock($lock);
  });
  //do your code
  $this->redlock->unlock($lock);
  return $result;
}

注解使用

class IndexController extends AbstractController
{
    /**
     * @RedLockAnnotation(resource="redlock-hyperf-test", poolName={"default"})
     */
    public function index() {}
}

SDK提供 RedlockHyperf\Annotation\RedLockAnnotation 注解,作用类于方法上,可以配置resource(必填),poolName,clockDriftFactor,ttl等参数