[框架系列]-[通用lock框架] 介绍

发布时间:2024年01月23日

目录

一:简介

二:框架优点

1.统一的调用api

2.统一的lock句柄获取api

3.多厂商实现切换

4.多厂商不同类型lock同时使用

5.多厂商实现扩展

6.lock增强

(1)本地lock预锁

(2)事务感知

7.注解式lock支持

(1)提供的lock注解

(2)业务策略及自定义策略

8.方法级定制以及全局定制能力


一:简介

lock框架是解决java lock领域的一种通用框架,基于spring boot框架starter集成机制,可以通过简单的依赖配置,快速实现集成,此篇主要介绍设计思路,不关心的直接具体见通用lock框架集成及具体配置使用-CSDN博客

二:框架优点

1.统一的调用api

基于java 的Lock接口作为标准,可以使用本地的ReentantLock,ReentrantReadWriteLock.WriteLock以及Redission相关的RedissonLock,RedissonReadLock 等接口的实现

public?interface?Lock {

????void?lock();

?????

????void?lockInterruptibly()?throws?InterruptedException;

?????

????boolean?tryLock();

?????

????boolean?tryLock(long?time, TimeUnit unit)?throws?InterruptedException;

???

????void?unlock();

???

????Condition newCondition();

}

2.统一的lock句柄获取api

基于Spring的LockRegistry标准,可以使用包括Spring自带的RedisLockRegistry以及其他实现此标准的LockRegistry

@FunctionalInterface

public?interface?LockRegistry {

????/**

?????* Obtains the lock associated with the parameter object.

?????* @param lockKey The object with which the lock is associated.

?????* @return The associated lock.

?????*/

????Lock obtain(Object lockKey);

}

LockRegistry obtain返回的Lock为java的Lock标准

3.多厂商实现切换

标准的高度统一,为灵活的切换不同的lock实现提供的支持。框架预置了如下实现类型的定义

/**

????* lock实现厂商类型

????*/

???public?enum?LockImplementer {

???????/**

????????* 本地JVM实现

????????*/

???????JVM,

???????/**

????????* redis实现

????????*/

???????REDIS,

???????/**

????????* zookeeper实现

????????*/

???????ZOOKEEPER,

???????/**

????????* etcd实现

????????*/

???????ETCD,

???????/**

????????* mysql实现

????????*/

???????MYSQL,

???????;

???}

其中本地实现以及redission实现框架已经支持

4.多厂商不同类型lock同时使用

/**

?* Created by suyouliang

?* Content :锁类型

?*/

public?enum?LockType {

????/**

?????* 可重入锁

?????*/

????Reentrant("reentrant"),

????/**

?????* 公平锁

?????*/

????Fair("fair"),

????/**

?????* 读锁

?????*/

????Read("read"),

????/**

?????* 写锁

?????*/

????Write("write"),

????/**

?????* 自旋锁

?????*/

????Spin("spin"),

????;

}

配置类型

配置名

作用域

LockImplementer
implementer
全局及注解
LockType
lockType
注解

5.多厂商实现扩展

框架允许基于Spring的标准LockRegistry扩展自定义的LockRegistry实现,当然Lock同样可以,通用Lock框架也基于这两个标准进行扩展的,并定义了本框架的扩展标准,实现一下以下接口后,仅需通过少量配置即直接可在框架中生效,而无需更改逻辑调用代码

public?interface?LockRegistryFactory {

????LockRegistry getLockRegistry(LockConfig.LockImplementer lockImplementer,?boolean?supportTransaction,?boolean?withLocalCache);

????LockFactory getLockFactory(LockConfig.LockImplementer lockImplementer,?boolean?supportTransaction,?boolean?withLocalCache);

}

public?interface?LockFactory {

????Lock getLock(String type, String lockKey);

????LockScopeType getScopeType();

}

6.lock增强

在java Lock定义的能力之外,框架提供了两个增强能力

(1)本地lock预锁

lock的上锁会先在本地进行预上锁,本地上锁成功才会真正调用实际的分布式锁。如果本地失败则直接快速失败

(2)事务感知

基于注解事务,内部使用lock可能会发生锁释放了但是当前事务还没提交的情况,此时lock将会失效。lock框架可感知上下文的事务,并提供了此情况发生时相应的策略

**

?* 当lock存在于事务上下文中的策略

?*/

public?enum?LockTransactionStrategy {

????/**

?????* 生效,打warming日志(仅开启supportTransaction生效)

?????*/

????WARMING,

????/**

?????* 禁止,会抛异常阻断业务逻辑(仅开启supportTransaction生效)

?????*/

????FORBIDDEN,

????/**

?????* 仅开启supportTransaction生效,

?????* 保证多线程访问安全,unlock会在事务完成后再提交。

?????* 缺点:会使lock的作用域膨胀。直至上下文事务完成

?????*/

????THREAD_SAFE;

}

开发者可以根据自己的业务需要使用。本地缓存及事务感知能力同样可作用于自定义的lock(基于包装实现)

7.注解式lock支持

框架实现了基于注解式的lock支持

(1)提供的lock注解

注解

简介

其他

@FailFastLock快速失败的lock
@LocalLockJVM实现的lock
@Lock顶层lock注解,支持所有策略及配置参数

@FailFastLock 和@LocalLock都是基于@Lock实现的,扩展注解主要是为了更好的语义以及使用体验,而无需指定多余的配置。比如@FailFastLock 就不用配置等待时间,因为等待时间是0

@Target(value = {ElementType.METHOD})

@Retention(value = RetentionPolicy.RUNTIME)

@Documented

public?@interface?FailFastLock {

????/**

?????* 锁的名称

?????*

?????* @return name

?????*/

????String name()?default?"";

????/**

?????* 自定义业务key

?????*

?????* @return keys

?????*/

????String[] keys()?default?{};

}

(2)业务策略及自定义策略

lock从获取句柄,到加锁并执行逻辑代码,最后解锁这个过程可能出现各种异常情况,注解提供了对于以上情况的处理能力

备注:当作用域为全局及注解时,注解的优先级高于全局的设置

策略点

策略名

可选作用域

具体策略

加锁失败的处理策略
lockFailStrategy
全局及注解

1.NO_OPERATION:继续执行业务逻辑,不做任何处理

2.FAIL_FAST:快速失败

3.KEEP_ACQUIRE:一直阻塞,直到获得锁,在太多的尝试后,仍会报错

4.CUSTOMER: 自定义,用于全局默认处理

定制的加锁失败的处理策略customLockFailStrategy注解用户指定,格式为方法的全限定名称
加锁异常的处理策略
lockExceptionStrategy
全局及注解

1.THROW_EXCEPTION:抛出异常

2.CUSTOMER:自定义,用于全局默认处理

释放锁时报错的处理策略
releaseTimeoutStrategy
全局及注解

1.NO_OPERATION:继续执行业务逻辑,不做任何处理

2.FAIL_FAST:快速失败,可自定义异常类及报错信息

3.CUSTOMER: 自定义,用于全局默认处理

自定义释放锁时已超时的处理策略
customReleaseTimeout
Strategy
全局及注解

用户指定,格式为方法的全限定名称

获取锁失败时,报错的异常类型全局及注解按照用户指定异常类型报错
获取锁失败时,报错的错误信息全局及注解按照用户指定异常信息报错
8.方法级定制以及全局定制能力

框架设计时考虑到用户的自定义需求,提供了方法级定制以及全局定制的能力,以上的策略中,lockFailStrategy,lockExceptionStrategy,releaseTimeoutStrategy 都提供了CUSTOMER的的策略,框架通过java的SPI机制,将对应的用户自实现的策略加载

策略点

策略名

具体配置名

扩展定义接口

加锁失败的处理策略lockFailStrategyCUSTOMERcn.techwolf.blue.usl.framework.lock.handler.lock.ExceptionOnLockCustomerHandler
加锁异常的处理策略lockExceptionStrategyCUSTOMERcn.techwolf.blue.usl.framework.lock.handler.lock.FailOnLockCustomerHandler
加锁释放锁异常的处理策略releaseTimeoutStrategyCUSTOMERcn.techwolf.blue.usl.framework.lock.handler.release.ReleaseTimeoutCustomerHandler

自定义处理策略加载后,如果需要指定为全局,需要在全局配置中指定定位的策略名的配置为CUSTOMER即可开启,方法级同理

注意:无论是全局还是注解的方法级,一旦指定以上策略的配置为CUSTOMER,则系统运行时必须存在对应的实现类,否则报错。不同的是,全局级配置报错将导致项目无法启动

文章来源:https://blog.csdn.net/qq_31457665/article/details/135766784
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。