1、导入相关依赖
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.0</version>
</dependency>
2、zookeeper的相关配置
# zk配置
curator:
retryCount: 5 #重试次数
baseSleepTimeMs: 1000 #重试间隔时间
connectString: 127.0.0.1:2181 # zk地址
sessionTimeoutMs: 60000 #session超时时间
connectionTimeoutMs: 5000 #连接超时时间
package com.cxb.springboot.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Classname WrapperZk
* @Description TODO
* @Date 2023/3/28 21:57
* @Created by Administrator
*/
@Data
@Component
@ConfigurationProperties(prefix = "curator")
public class WrapperZk {
private int retryCount;
private int elapsedTimeMs;
private String connectString;
private int sessionTimeoutMs;
private int connectionTimeoutMs;
private int baseSleepTimeMs;
}
package com.cxb.springboot.config;
import lombok.extern.slf4j.Slf4j;
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.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* @Classname ZkConfiguration
* @Description TODO
* @Date 2023/3/28 21:57
* @Created by Administrator
*/
@Configuration
@Slf4j
public class ZkConfiguration {
@Resource
WrapperZk wrapperZk;
/**
* 其中RetryPolicy为重试策略,第一个参数为baseSleepTimeMs初始的sleep时间,
* 用于计算之后的每次重试的sleep时间。第二个参数为maxRetries,最大重试次数。
* @return
*/
@Bean(initMethod = "start")
public CuratorFramework curatorFramework() {
RetryPolicy retrYPolicy = new ExponentialBackoffRetry(wrapperZk.getBaseSleepTimeMs(),
wrapperZk.getRetryCount());
CuratorFramework client = CuratorFrameworkFactory
.newClient(wrapperZk.getConnectString(), retrYPolicy);
log.info("zk curator初始化完成...");
return client;
}
}
3、使用多线程模拟抢占锁
package com.cxb.springboot.controller;
import com.cxb.springboot.config.ZkConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @Classname MicroController
* @Description TODO
* @Date 2023/3/28 22:03
* @Created by Administrator
*/
@Controller
@RequestMapping("/zk")
@Slf4j
public class MicroController {
private final static String PATH = "/rootLock";
@Autowired
ZkConfiguration zkConfiguration;
/**
* 这里我用的是最常用的可重入排他锁,也是公平锁(InterProcessMutex)
* InterProcessMutex:分布式可重入排它锁
* InterProcessSemaphoreMutex:分布式排它锁
* InterProcessReadWriteLock:分布式读写锁
* InterProcessMultiLock:将多个锁作为单个实体管理的容器
* @return
* @throws Exception
*/
@RequestMapping("/lock")
@ResponseBody
public String getLock1() throws Exception {
InterProcessMutex lock = new InterProcessMutex(zkConfiguration.curatorFramework(), PATH);
for (int i = 0; i < 30; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
log.info(Thread.currentThread().getName() + "尝试获取锁....");
lock.acquire();
log.info(Thread.currentThread().getName() + "获取锁成功....");
log.info(Thread.currentThread().getName() + "开始执行业务逻辑....");
Thread.sleep(10000);
lock.release();
log.info(Thread.currentThread().getName() + "释放锁成功....");
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
return "execute success";
}
}
调用接口: http://localhost:8081/zk/lock 然后使用zookeeper的可视化工具查看当前节点的信息。
等待任务执行完成之后,所有的节点信息都会被移除