分布式锁2-Zookeeper分布式锁实战
Zookeeper分布式锁实战
使用curator操作Zookeeper进行实战;
curator是什么:Apache Curator包含一套高级API框架和工具类,它 是Apache ZooKeeper 的Java 客户端库。
准备
- pom文件引入curtor依赖和zookeeper依赖
<!--curator-->
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>5.6.0</version>
</dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>5.6.0</version></dependency>
<!--zookeeper-->
<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.9.2</version>
</dependency>
- yml配置
#zookeeper
curator:connectString: localhost:2181retryCount: 5elapsedTimeMs: 5000sessionTimeOutMs: 60000connectionTimeOutMs: 5000
- 配置类
/*** @Author * @Date 2024/5/19 19:45*/
@Data
@Component
@ConfigurationProperties(prefix = "curator")
public class WrapperZK {/** 重试次数*/private int retryCount;/** 重试间隔时间*/private int elapsedTimeMs;/** 连接地址*/private String connectString;/** session超时时间*/private int sessionTimeOutMs;/** 连接超时时间*/private int connectionTimeOutMs;
}
@Configuration
public class ZookeeperConfig {@Autowiredprivate WrapperZK wrapperZK;@Beanpublic CuratorFramework curatorFramework(){RetryPolicy retryPolicy = new ExponentialBackoffRetry(wrapperZK.getElapsedTimeMs(),wrapperZK.getRetryCount());CuratorFramework client = CuratorFrameworkFactory.newClient(wrapperZK.getConnectString(), wrapperZK.getSessionTimeOutMs(), wrapperZK.getConnectionTimeOutMs(), retryPolicy);client.start();return client;}
}
- 使用
@Autowiredprivate CuratorFramework curatorFramework;static InterProcessLock zkLock;/** 使用zookeeper分布式锁 */@Transactionalpublic void updateByZookeeperLock(Long id,int count){if(zkLock == null){zkLock = new InterProcessMutex(curatorFramework, "/locks");}try {boolean acquire = zkLock.acquire(10000, TimeUnit.MILLISECONDS);/** 加锁*/if(acquire){Product product = mapper.selectById(id);int newCont = product.getProductCount() - count;product.setProductCount(newCont);if(mapper.updateProduct(product) >0 ){System.out.println("扣减成功!");}else {throw new RuntimeException("扣减失败");}}else {System.out.println("拿不到分布式锁!");}}catch (Exception e){e.printStackTrace();}finally {try {/** 释放锁*/zkLock.release();} catch (Exception e) {throw new RuntimeException(e);}}}
@RestController
@RequestMapping("/product")
public class ProductController {@Autowiredprivate ProductService service;@GetMapping("buy/{id}/{count}")public void buy(@PathVariable long id,@PathVariable int count){service.updateByZookeeperLock(id,count);}
}
- 测试
压测前:
压测:
压测后:
成功!