定制 happysir/distributed-lock 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

happysir/distributed-lock

Composer 安装命令:

composer require happysir/distributed-lock

包简介

A distributed lock based on PHP and redis(swoft)

README 文档

README

[TOC]

加锁是访问临界资源时对资源的保护机制,加锁的目的是对并发访问和并发请求进行保护,未获取到锁的请求将无权操作资源。

临界区域指的是一块对公共资源进行访问的代码,并非一种机制或是算法。一个程序、进程、线程可以拥有多个临界区域

安装

composer require happysir/distributed-lock

配置

use Happysir\Lock\RedisLock;
use Swoft\Redis\Pool;
use Swoft\Redis\RedisDb;

return [
    // redis db
    'redis'            => [
        'class'    => RedisDb::class,
        'host'     => '127.0.0.1',
        'port'     => 6379,
        'database' => 0,
        'option'   => [
            'prefix'     => 'swoft:',
            'serializer' => Redis::SERIALIZER_NONE
        ]
    ],
    // redis pool
    Pool::DEFAULT_POOL => [
        'class'       => Pool::class,
        'redisDb'     => \bean('redis'),
        'minActive'   => 10,
        'maxActive'   => 20,
        'maxWait'     => 0,
        'maxWaitTime' => 0,
        'maxIdleTime' => 60,
    ],
    // redis lock
    RedisLock::class   => [
        // redis pool
        'pool' => Pool::DEFAULT_POOL,
    ]
];

详细参数:

  • pool Redis 连接池

使用

注解方式

当前组件提供了注解的方式使用分布式锁,使用方式如下:

<?php declare(strict_types=1);

namespace App\Http\Controller;

use Happysir\Lock\Annotation\Mapping\DistributedLock;
use Swoft\Context\Context;
use Swoft\Http\Message\Request;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Http\Server\Router\Router;
use Swoft\View\Renderer;
use Swoole\Coroutine;
use Throwable;

/**
 * Class HomeController
 * @Controller()
 */
class HomeController
{
    /**
     * @RequestMapping("/")
     * @DistributedLock(key="request.getUriPath()~':'~request.query('id')",ttl=6,type=DistributedLock::RETRY_TO_GET)
     * @throws Throwable
     */
    public function index(Request $request): Response
    {
        Coroutine::sleep(1);
        
        return context()->getResponse();
    }

    /**
     * @RequestMapping("/hello")
     * @DistributedLock(key="hello~':'~request.query('id')",ttl=6,type=DistributedLock::NON_BLOCKING)
     * @throws Throwable
     */
    public function hello(Request $request): Response
    {
        Coroutine::sleep(1);
        
        return context()->getResponse();
    }
}

@DistributedLock注解说明

  • key 锁资源唯一标识key,同一时间片只能由一个线程持有
  • type 锁类型
    • DistributedLock::NON_BLOCKING类型,在获取锁失败时会直接抛出DistributedLockException异常
    • DistributedLock::RETRY_TO_GET类型,在获取锁失败时,会重新尝试获取锁(每0.5s重试一次,最多重试retries次),超过最大重试次数后会抛出DistributedLockException异常
  • ttl 锁的有效时间(ttls后锁会自动过期)
  • errcode 尝试持有锁时抛出的异常对应的code
  • errmsg 尝试持有锁时抛出的异常对应的msg
  • retries 重试次数(需要注意的是,重试次数过多,可能会造成系统负载上升,因此硬性限制最大重试次数为10次)

key 这里支持 symfony/expression-language 表达式,可以实现很多复杂的功能,详细文档。key 表达式内置 CLASS(类名) 和 METHOD(方法名称) 两个变量,方便开发者使用。详细使用参考Swoft服务限流章节

代码方式(显式使用)

DistributedLock::NON_BLOCKING
use Happysir\Lock\RedisLock;
$distributedLock = bean(RedisLock::class);

if (!$distributedLock->tryLock('test', 1)) {
    return false;
}

// 业务逻辑...

$distributedLock->unLock();
DistributedLock::RETRY_TO_GET
use Happysir\Lock\RedisLock;
$distributedLock = bean(RedisLock::class);

// 加锁1s,重试3次
if (!$distributedLock->lock('test', 1, 3)) {
    return false;
}

// 业务逻辑...

$distributedLock->unLock();

看门狗机制

存在这样一种场景,业务代码较为复杂,执行时长会超过我们申请锁的时间,这时候就可能有第二个线程成功申请锁,未达到我们想要的保护目的。

针对这样的场景,我们在组件中支持了锁自动续约机制-看门狗任务。

当我们成功获取锁后,程序会为我们创建一个协程,此协程的作用是续约我们的锁的过期时间。在锁被释放或者当前请求结束后,此协程会自动退出。

happysir/distributed-lock 适用场景与选型建议

happysir/distributed-lock 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 124 次下载、GitHub Stars 达 6, 最近一次更新时间为 2019 年 08 月 04 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 happysir/distributed-lock 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 happysir/distributed-lock 我们能提供哪些服务?
定制开发 / 二次开发

基于 happysir/distributed-lock 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 124
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 6
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 6
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: Apache-2.0
  • 更新时间: 2019-08-04