一 使用临时节点实现分布式锁
1.1 代码截图
1.2 代码如下
由于zookeeper获取链接是一个耗时过程,这里可以在项目启动时,初始化链接,并且只初始化一次。借助于spring特性,代码实现如下:
package com.atguigu.distributed.lock.config;import org.apache.zookeeper.*;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.CountDownLatch;/*** @ClassName: ZkClient* @Description: TODO* @Author: admin* @Date: 2024/01/03 15:29:19 * @Version: V1.0**/
@Component
public class ZkClient {private static final String connectString = "192.168.43.4:2181";private static final String ROOT_PATH = "/d-zk";private ZooKeeper zooKeeper;@PostConstructpublic void init(){//获取连接,项目启动时CountDownLatch countDownLatch = new CountDownLatch(1);try {// 连接zookeeper服务器this.zooKeeper = new ZooKeeper(connectString, 30000, new Watcher() {@Overridepublic void process(WatchedEvent event) {Event.KeeperState state = event.getState();if (Event.KeeperState.SyncConnected.equals(state)&&Event.EventType.None.equals(event.getType())){System.out.println("获取链接成功!!");countDownLatch.countDown();}else if(Event.KeeperState.Closed.equals(state)){System.out.println("==================关闭链接成功!!");}}});countDownLatch.await();// 创建分布式锁根节点if (this.zooKeeper.exists(ROOT_PATH, false) == null){//节点类型为持久化父节点this.zooKeeper.create(ROOT_PATH, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);System.out.println("创建分布式锁根节点。。。。。。。");}} catch (Exception e) {System.out.println("获取链接失败!");e.printStackTrace();}}@PreDestroypublic void destroy(){try {if (zooKeeper != null){zooKeeper.close();}} catch (InterruptedException e) {e.printStackTrace();}}/*** 初始化zk分布式锁对象方法* @param lockName* @return*/public ZkDistributedLock getZkDistributedLock(String lockName){return new ZkDistributedLock(zooKeeper, lockName);}
}
分布式锁实现类:
package com.atguigu.distributed.lock.config;import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;/*** @ClassName: ZkDistributedLock* @Description: TODO* @Author: admin* @Date: 2024/01/03 15:32:05 * @Version: V1.0**/
public class ZkDistributedLock implements Lock {private static final String ROOT_PATH = "/d-zk";private String path;private ZooKeeper zooKeeper;public ZkDistributedLock(ZooKeeper zooKeeper, String lockName){this.zooKeeper = zooKeeper;this.path = ROOT_PATH + "/" + lockName;}/*** @author admin* @description 上锁* @date 2024/1/3 15:32* @param []* @return void*/public void lock(){this.tryLock();}@Overridepublic void lockInterruptibly() throws InterruptedException {}@Overridepublic boolean tryLock() {try {//创建临时节点zooKeeper.create(path, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);return true;} catch (Exception e) {// 。。。。。。。。。。。。。。。。。。。。。重试自旋。。。。。。。。。。。。。。。。。。。。。。。。try {Thread.sleep(200);this.tryLock();} catch (InterruptedException ex) {ex.printStackTrace();}}return false;}@Overridepublic boolean tryLock(long time, TimeUnit unit) throws InterruptedException {return false;}/*** @author admin* @description 解锁* @date 2024/1/3 15:33* @param []* @return void*/public void unlock(){try {this.zooKeeper.delete(path, 0);} catch (InterruptedException e) {e.printStackTrace();} catch (KeeperException e) {e.printStackTrace();}}@Overridepublic Condition newCondition() {return null;}
}
3.修改service
4.修改controller
1.3 单笔测试
1.debug放问:http://localhost:9999/stock/deduct
2.查看
3.查看znode节点
4.查看数据库
1.4 nginx反向代理多节点
1.nginx配置
2.启动nginx
3.工程多服务端口启动
1.4 jemeter 压力测试
1.初始数据库
2.设置jemter
3.查看两个服务
端口:10087
端口:10086
4.查看数据库
5.查看 jemeter压测结果