Skip to content

weicut/synchronized

Folders and files

NameName
Last commit message
Last commit date

Latest commit

author
fangjw
Jun 11, 2021
404804f · Jun 11, 2021

History

15 Commits
Jun 9, 2021
Jun 11, 2021
Jun 11, 2021
Jun 9, 2021
Jun 9, 2021
Jun 9, 2021
Jun 11, 2021
Jun 11, 2021

Repository files navigation

Synchronized

hyperf/synchronized 提供了基于 redisconsul 实现的高效互斥锁注解,底层通过增加 自旋锁 特性解决轮询带来的大量网络消耗,目前仅支持 METHOD 注解,后续还会补充 etcdredlock 等等相关锁

安装

composer require hyperf/synchronized

默认配置

通过 php bin/hyperf.php vendor:publish hyperf/synchronized 安装配置

return [

    'redis' => [
        'store' => \Hyperf\Synchronized\Store\RedisStore::class, // redis 锁
        'options' => [
            'pool' => 'default', // redis.php 配置的 pool 配置
        ],
    ],

    'consul' => [
        'store' => \Hyperf\Synchronized\Store\ConsulStore::class, // consul 锁
        'options' => [
            'uri' => 'http://127.0.0.1:8500',
            'token' => ''
        ],
    ],

];

注解参数

配置 默认值 备注
mode 1 锁模式,1:阻塞,2:异常
secondsTimeout 3 超时时间,仅阻塞模式下有效,单位:秒
store redis synchronized.php 中的 store 配置
withParam true false:方法锁,true:方法 + 参数锁,由此控制锁的粒度

使用

阻塞锁

任何时刻只会存在一个锁,当某个调用进入临界点后,其余调用会进行 阻塞,直到锁解除或者超时。此模式不建议使用在请求量较大的场景中,因为阻塞行为容易引起 惊群效应

<?php

declare(strict_types=1);

namespace App\Service;

use Hyperf\Synchronized\Annotation\Synchronized;
use Hyperf\Synchronized\LockMode;
use Hyperf\Utils\Parallel;

class BlockService
{

    public function test(){

        $startTime = microtime(true);
        $parallel = new Parallel(5);
        $parallel->add([$this, 'handler']);
        $parallel->add([$this, 'handler']);
        $parallel->add([$this, 'handler']);
        $parallel->add([$this, 'handler']);
        $parallel->add([$this, 'handler']);
        $parallel->wait();
        $endTime = microtime(true);
        echo ($endTime- $startTime).PHP_EOL;
    }

    /**
     * @Synchronized(mode=LockMode::BLOCK, secondsTimeout=3)
     */
    public function handler(): void
    {
        sleep(1);
    }
}

异常锁

任何时刻只会存在一个锁,当某个调用进入临界点后,其余调用会抛 Hyperf\Synchronized\Exception\AcquireException 异常。业务自行捕获处理,重试或者直接向客户端返回特定错误码,由客户端进行定时重试,减轻服务端连接负荷。 此模式比较合适请求量大的场景

<?php

declare(strict_types=1);

namespace App\Service;

use Hyperf\Synchronized\Annotation\Synchronized;
use Hyperf\Synchronized\Exception\AcquireException;
use Hyperf\Synchronized\LockMode;
use Hyperf\Utils\Coroutine;

class ExceptionService
{

    public function test(){

        for($i = 0; $i < 10; $i ++){

            Coroutine::create(function(){
                try {
                    $this->handler();
                }catch (AcquireException $exception){
                    
                }
            });
        }
    }

    /**
     * @Synchronized(mode=LockMode::EXCEPTION)
     */
    public function handler(): void
    {
        sleep(1);
    }
}

About

A synchronized for hyperf.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages