Curator实现分布式锁代码
Curator环境搭建
Maven依赖
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.2.0</version> </dependency>
核心api配置
package com.shanhe.config; import org.apache.curator.RetryPolicy; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.utils.CloseableUtils; import org.springframework.stereotype.Component; /** * zk框架实现分布式锁 */ @Component public class CuratorZkLock { // ZooKeeper 服务地址, 单机格式为:(127.0.0.1:2181), // 集群格式为:(127.0.0.1:2181) private String connectString; // Curator 客户端重试策略 private RetryPolicy retry; // Curator 客户端对象 private CuratorFramework client; public CuratorZkLock() throws Exception { init(); } public void init() throws Exception { // 设置 ZooKeeper 服务地址为本机的 2181 端口 connectString = "127.0.0.1:2181"; // 重试策略 // 初始休眠时间为 1000ms, 最大重试次数为 3 retry = new ExponentialBackoffRetry(1000, 3); // 创建一个客户端, 60000(ms)为 session 超时时间, 15000(ms)为连接超时时间 client = CuratorFrameworkFactory.newClient(connectString, 60000, 15000, retry); client.start(); } public void close() { CloseableUtils.closeQuietly(client); } public CuratorFramework getClient() { return client; } }
简单用法
package com.shanhe.service; import com.shanhe.config.CuratorZkLock; import com.shanhe.entity.CommodityDetails; import com.shanhe.mapper.CommodityDetailsMapper; import lombok.extern.slf4j.Slf4j; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.TimeUnit; @RestController @Slf4j public class SeckillService { @Autowired private CuratorZkLock curatorZkLock; // ZooKeeper 锁节点路径, 分布式锁的相关操作都是在这个节点上进行 private final String lockPath = "/distributed-lock"; @Autowired private CommodityDetailsMapper commodityDetailsMapper; /** * 秒杀lock * * @return */ @RequestMapping("/seckilLock") public String seckilLock() throws Exception { InterProcessMutex interProcessMutex = null; try { CuratorFramework client = curatorZkLock.getClient(); // 获取锁 底层 zk上创建一个临时顺序编号节点 interProcessMutex = new InterProcessMutex(client, lockPath); //获取锁 一直没有获取锁成功的情况下,默认是会阻塞。 interProcessMutex.acquire(); log.info("<获取锁成功....>"); log.info("<执行秒杀扣库存业务逻辑....>"); CommodityDetails commodityDetails = commodityDetailsMapper.getCommodityDetails(1L); Long stock = commodityDetails.getStock(); if (stock > 0) { log.info("<开始执行扣库存..>"); int result = commodityDetailsMapper.reduceInventory(1l); return result > 0 ? "扣库存成功" : "扣库存失败"; } // 扣库存失败 log.info("<扣库存失败>"); return "fail"; } catch (Exception e) { e.printStackTrace(); log.error("<秒杀出现错误:e:{}>", e); return "fail"; } finally { // 释放锁 if (interProcessMutex != null) interProcessMutex.release(); } } }
早年同窗始相知,三载瞬逝情却萌。年少不知愁滋味,犹读红豆生南国。别离方知相思苦,心田红豆根以生。