kekingcn / spring-boot-klock-starter Goto Github PK
View Code? Open in Web Editor NEW基于redis的分布式锁组件,简单方便快捷接入项目,使项目拥有分布式锁能力
Home Page: https://gitee.com/kekingcn/spring-boot-klock-starter
License: Apache License 2.0
基于redis的分布式锁组件,简单方便快捷接入项目,使项目拥有分布式锁能力
Home Page: https://gitee.com/kekingcn/spring-boot-klock-starter
License: Apache License 2.0
String curentLock = this.getCurrentLockId(joinPoint,klock); currentThreadLock.put(curentLock,new LockRes(lockInfo, false));
加锁时,这里的key是线程id+锁名。当同一线程重入这把锁时,内层释放时:
// avoid memory leak private void cleanUpThreadLocal(String curentLock) { currentThreadLock.remove(curentLock); }
会把这把锁从map里remove掉,在外层再释放时,就拿不到锁信息了:
private void releaseLock(Klock klock, JoinPoint joinPoint,String curentLock) throws Throwable { LockRes lockRes = currentThreadLock.get(curentLock); if (lockRes.getRes()) { boolean releaseRes = currentThreadLock.get(curentLock).getLock().release(); // avoid release lock twice when exception happens below lockRes.setRes(false); if (!releaseRes) { handleReleaseTimeout(klock, lockRes.getLockInfo(), joinPoint); } } }
是否应该加上计数器支持重入性?
Can't init enough connections amount! Only 0 from 1 were initialized. 这是咋回事啊 大佬
不支持redis Sentinel集群么?
Hello
@KlockKey 业务key 参数为null是会报空指针
KlockKey keyAnnotation = parameters[i].getAnnotation(KlockKey.class);
if (keyAnnotation.value().isEmpty()) {
parameterKey.add(parameterValues[i].toString());
}
try {
currentThreadLock = lock.acquire();
return joinPoint.proceed();
} finally {
if (currentThreadLock) {
lock.release();
}
}
这是是不是应该改成
try {
currentThreadLock = lock.acquire();
if (currentThreadLock) {
joinPoint.proceed();
}
return null;
} finally {
if (currentThreadLock) {
lock.release();
}
}
拿到锁再执行业务逻辑
在同一线程中,如果由一个带klock锁(锁A)的方法调用另一个带klock锁(锁B)的方法,currentThreadLock中的锁信息将会更新(锁A->锁B),
currentThreadLock.set(lock); currentThreadLockRes.get().setRes(true);
并且在两个方法退出时,都会触发KlockAspectHandler类中releaseLock方法的调用,
LockRes lockRes = currentThreadLockRes.get(); if (lockRes.getRes()) { boolean releaseRes = currentThreadLock.get().release(); // avoid release lock twice when exception happens below lockRes.setRes(false); if (!releaseRes) { handleReleaseTimeout(klock, lockRes.getLockInfo(), joinPoint); } }
由于第一次触发时,currentThreadLock和currentThreadLockRes中的锁信息会被清空,所以第二次触发将会报NPE。请教下,这种单一线程只支持加一次锁的设计,是有什么原因吗?另在有currentThreadLock这个ThreadLocal保证单一线程只有一个锁有效的前提下,currentThreadLockRes存在的意义是什么?
maven添加此依赖,无法找到
只有
cn.keking
spring-boot-klock-starter
1.1-RELEASE
还请补全快速开始之类的文档,感谢分享
redis连接池不用配置吗
我测试 没有配置
spring.klock.address : redis链接地址
spring.klock.password : redis密码
spring.klock.database : redis数据索引
也可以使用,是否使用了默认的redis配置
redis:
host: xxx
port: xxx
password: xxxxx
database: 3
这样是不是可以不再配置 klock 也是可以使用的
@PostConstruct
public void init(){
lockMap.put(LockType.Reentrant,new ReentrantLock(redissonClient));
lockMap.put(LockType.Fair,new FairLock(redissonClient));
lockMap.put(LockType.Read,new ReadLock(redissonClient));
lockMap.put(LockType.Write,new WriteLock(redissonClient));
logger.info("Klock Initialization Successful");
}
public Lock getLock(ProceedingJoinPoint joinPoint, Klock klock){
LockInfo lockInfo = lockInfoProvider.get(joinPoint,klock);
return lockMap.get(lockInfo.getType()).setLockInfo(lockInfo);
}
根据LockFactory这个类,每种类型永远只有一把锁??? 也就是同一个系统类,如果两个接口没什么关系,但是如果都用了公平锁,就意味着两个接口存在锁竞争?
你好,如何控制最大连接数呢?有没有配置可以限制?
如果要放到spring mvc项目中使用,请问应该怎么配置呢
非常棒的工具,但是现在已经2022年,springboot都已经到2.7了,有考虑适配升级一下?
rLock为static,当多把锁同时上锁的时候,rLock难道不会发生改变吗?
klock-spring-boot-starter
这个项目不错👍
给几点使用的建议:
spring:
klock:
address: ${spring.redis.host}+${spring.redis.port}
password: ${spring.redis.password}
database: ${spring.redis.database}
hello 作者,
我们项目需要用到分布式锁,觉得你这个项目非常棒,但很多依赖库都非常旧了,我们是基于Spring-boot 2.1.8 开发的应用,各种不兼容,需要拉去代码升级里面的spring库重新编译才可以使用。请问现在还维护吗,我给你提一个PR然后重新发布一个高版本的包
我有两个方法
一个写操作, 一个读操作
想在这两个方法上面使用@klock注解
实际没用, 因为两个方法上面的锁key都不一样
org.springframework.boot.autoconfigure.klock.core.KlockAspectHandler - Timeout while acquiring Lock(lock.com.example.game.controller.OrderController.xxxx)
一个集群一个服务部署了多个副本,通过xxl-job内部调接口提示一直被锁,返回失败。但如果我用swagger单独调该接口是没有问题的,我看了一下redis里面的数据,也没有上锁的key。如果是服务没有多副本的情况也是不会报错的,请问这是什么情况呢。具体的报错如下:
org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 : [{"timestamp":"2024-03-05T06:41:16.013+00:00","status":500,"path":"/v1/things/job-handler/cal-things-usage","code":"http.500","error":"Internal Server Error","message":"Failed to acquire Lock(lock.com.things.api.JobHandlerController.calThingsUsage) with timeout(1s)"}]
@klock可以标注四个参数,作用分别如下
name:lock的name,对应redis的key值。默认为:类名+方法名
我根据这个属性,想实现这个方法加锁(有参数), 不管参数值是什么,但得不到我想要的结果.
最后发现LockInfoProvider这个类中获取lock的name,会加上businessKeyName,
是我理解错了这个参数的意思? 按照文档的描述,加上@KlockKey才应该是这样的结果,
或者有其他方式可以实现我的需求?
keys里面目前支持添加常量么?还有从实体类里取值做key的时候,当某个取值是null的时候,会报空指针,这个能否优化下?多谢
默认读取系统的redis然后注入,不需要那么复杂,或者找不到时默认注入session对象也行
您好,在springboot项目中,运用了klock,用法如下:
@klock
@scheduled(fixedRate = 500)
public get(){
}
klock配置如下:
waitTime: 600
leaseTime: 600
但发现偶尔还是会导致get方法执行两次,请问下我的用法是否有问题?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.