分布式锁在主流实现技术上主要有以下三种:
至于优劣可参考另外一篇博客。本篇博客演示的是zookeeper结合apache的curator实现分布式锁。
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
<exclusions>
<!-- 防止zookeeper版本冲突 -->
<exclusion>
<artifactId>zookeeper</artifactId>
<groupId>org.apache.zookeeper</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
<exclusions>
<exclusion>
<artifactId>zookeeper</artifactId>
<groupId>org.apache.zookeeper</groupId>
</exclusion>
</exclusions>
</dependency>
application.yml
zookeeper:
servers: localhost:2181,localhost:2182 # 换成自己的环境
lockPath: /lock/ # 指定分布式锁路径
sessionTimeoutMs: 60000 # session超时时间
connectionTimeoutMs: 5000 # 连接超时时间
retryCount: 5 # 尝试获取锁最大重试次数
elapsedTimeMs: 1000 # 重试间隔时间
@Data
@Component
@ConfigurationProperties(prefix = "zookeeper")
public class ZookeeperConfigurer {
/** 尝试次数 */
private int retryCount;
/** 重试间隔时间 */
private int elapsedTimeMs;
/** session超时时间 */
private int sessionTimeoutMs;
/** 连接超时时间 */
private int connectionTimeoutMs;
/** zookeeper集群地址 */
private String servers;
/** zookeeper分布式锁跟路径 */
private String lockPath;
}
@Configuration
public class CuratorConfigurer {
@Autowired
private ZookeeperConfigurer zkConfigurer;
@Bean(initMethod = "start", destroyMethod = "close")
public CuratorFramework curatorFramework() {
return CuratorFrameworkFactory.newClient(
zkConfigurer.getServers(),
zkConfigurer.getSessionTimeoutMs(),
zkConfigurer.getConnectionTimeoutMs(),
new RetryNTimes(zkConfigurer.getRetryCount(), zkConfigurer.getElapsedTimeMs()));
}
}
/**
* <p> 分布式锁注解 <p>
* @author lamandonet@163.com
* @version 1.0.0
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DistributedLock {
String name() ;
}
@Aspect
@Component
public class DistributedLockAspect {
@Autowired
private CuratorFramework curatorFramework;
@Pointcut("@annotation(com.clickpaas.annotation.DistributedLock)")
public void distributedLockAspect() {}
@Around(value = "distributedLockAspect()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
// target class
Class<?> targetClass = pjp.getTarget().getClass();
// method name
String methodName = pjp.getSignature().getName();
// parameter types
Class<?>[] parameterTypes = ((MethodSignature) pjp.getSignature()).getMethod().getParameterTypes();
// method
Method method = targetClass.getMethod(methodName, parameterTypes);
// arguments
Object[] arguments = pjp.getArgs();
return lock(pjp, method, arguments);
}
private Object lock(ProceedingJoinPoint pjp, Method method, Object[] arguments) throws Throwable {
DistributedLock annotation = method.getAnnotation(DistributedLock.class);
String lockName = parseKey( annotation, method, arguments );
InterProcessMutex mutex = new InterProcessMutex(curatorFramework, zookeeperConfigurer.getLockPath() + lockName);
if ( mutex.acquire(0, TimeUnit.SECONDS) ) {
return pjp.proceed();
}
return null;
}
private String parseKey(DistributedLock annotation, Method method, Object[] args){
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String [] paraNameArr = u.getParameterNames(method);
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
for(int i=0; i<paraNameArr.length; ++i){
context.setVariable(paraNameArr[i], args[i]);
}
String lockName = annotation.name();
if(lockName.contains("#")) {
lockName = parser.parseExpression(lockName).getValue(context, String.class);
}
return lockName;
}
@AfterThrowing(value = "distributedLockAspect()", throwing="ex")
public void afterThrowing(Throwable ex) {
throw new RuntimeException(ex);
}
}
不好意思,不经常逛博客,不用手动调用,已经使用切面了肯定是在切面里面进行统一释放,demo比较粗糙,忘记写了。
InterProcessMutex mutex = new InterProcessMutex(curatorFramework, zookeeperConfigurer.getLockPath() + lockName);
if ( mutex.acquire(0, TimeUnit.SECONDS) ) {
try{
return pjp.proceed();
} finally {
mutex.release();
}
}
原网址: 访问
创建于: 2020-12-03 16:56:03
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论