一 使用临时节点实现分布式锁
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;
@PostConstruct
public void init(){
//获取连接,项目启动时
CountDownLatch countDownLatch = new CountDownLatch(1);
try {
// 连接zookeeper服务器
this.zooKeeper = new ZooKeeper(connectString, 30000, new Watcher() {
@Override
public 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();
}
}
@PreDestroy
public 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();
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public 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;
}
@Override
public 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();
}
}
@Override
public 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压测结果