基于zookeeper分布式锁

2021-02-20 16:38发布

    最近项目中新上线了抢优惠券功能,虽然用户不多但是,如何防止超发呢?单体应用情况下只需要在抢券方法前用synchronized修饰即可,但是目前大部分项目都是分布式微服务架构,所以就需要加分布式锁。项目用的SpringMVC+dubbo,注册中心使用的zookeeper,所以就选用的基于zookeeper的分布式锁。

原生的zookeeper分布式锁写起来比较复杂,使用zookeeper的Curator框架轻松实现,代码实现:

pom文件

<dependency>
   <groupId>org.apache.zookeeper</groupId>
   <artifactId>zookeeper</artifactId>
   <version>3.4.6</version>
</dependency>
<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-recipes</artifactId>
   <version>4.0.1</version>
</dependency>

Spring集成

<!-- 重连策略 -->
<bean id="retryPolicy" class="org.apache.curator.retry.ExponentialBackoffRetry">
   <!-- 间隔时间基数 -->
   <constructor-arg index="0" value="1000" />
   <!-- 重连策略 -->
   <constructor-arg index="1" value="3" />
</bean>

<bean id="curatorFramework" class="org.apache.curator.framework.CuratorFrameworkFactory" factory-method="newClient" init-method="start">
   <constructor-arg index="0" value="#{globalConfig.zk_address}" />
   <!-- sessionTimeoutMs会话超时时间,单位为毫秒。默认是60000ms  -->
   <constructor-arg index="1" value="5000" />
   <!-- connectionTimeoutMs连接创建超时时间,单位毫秒,默认15000ms -->
   <constructor-arg index="2" value="3000" />
   <constructor-arg index="3" ref="retryPolicy" />
</bean>

@Autowired    

private CuratorFramework curatorFramework;

//定义锁路径

String path = "/lock/discount/" + discountId;        

InterProcessMutex lock = new InterProcessMutex(curatorFramework, path);

//获取锁 

if (lock.acquire(3000, TimeUnit.MILLISECONDS)) {

//do something

}

//释放锁

lock.release();

分布式锁配合事务使用时,不要加到事务方法上,在外层调用者上加锁,否则存在事务未提交即获取锁;

标签: