curator对zookeeper 进行了封装,提供了强大API,介绍下对节点常用操作
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-clientartifactId>
<version>2.13.0version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
<version>2.13.0version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-recipesartifactId>
<version>2.13.0version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.4version>
dependency>
server.port=8080
spring.application.name=zk_demo_1
#zk 配置,最好配置多个地址
zookeeper.address=192.168.30.129:2181
zookeeper.timeout=5000
zookeeper.maxRetries=2
NodeModel
/**
* @author guanzc
* @version 产品版本信息 Mar 19, 2018 姓名(邮箱) 修改信息
*/
@Data
@ApiModel(value="zk对象")
@Accessors(chain=true)
public class NodeModel {
@ApiModelProperty(value = "节点名称", required = true)
private String nodePath;
@ApiModelProperty(value = "节点数据", required = false)
private String nodeData;
@ApiModelProperty(value = "是否递归创建节点, 默认false,不递归创建")
private boolean isrecursion;
}
选主发生在启动时,需要创建客户端
初始加载
/**
* @author guanzc
* @version 产品版本信息 Mar 19, 2018 姓名(邮箱) 修改信息
*/
package com.zk.config;
import com.zk.server.CuratorClientInitService;
import org.apache.curator.framework.CuratorFramework;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* @author guanzc
* @version 产品版本信息 Mar 19, 2018 姓名(邮箱) 修改信息
*/
@Component
public class DemoInit implements CommandLineRunner {
@Autowired
private CuratorClientInitService curatorClientInitService;
private CuratorFramework client = null;
public void run(String... args) throws Exception {
if (client == null) {
client = curatorClientInitService.getCuratorFrameworkClient();
}
}
}
选主
/**
* @author guanzc
* @version 产品版本信息 Mar 19, 2020 姓名(邮箱) 修改信息
*/
package com.zk.server;
import com.zk.config.Constants;
import lombok.SneakyThrows;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.leader.LeaderLatch;
import org.apache.curator.framework.recipes.leader.LeaderLatchListener;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class ZkJudgeElectorService {
@Value("${spring.application.name}")
private String appName;
@Value("${server.port}")
private String port;
private LeaderLatch latch = null;
/**
* 选主节点
*
* @param
* @return LeaderLatch
*/
public LeaderLatch createLatch(CuratorFramework client) {
try {
if (latch != null) {
return latch;
}
String judgeLeader = appName + ":" + port;
latch = new LeaderLatch(client, Constants.judge_path, judgeLeader);
CuratorFramework client = client;
latch.addListener(new LeaderLatchListener() {
@SneakyThrows
public void isLeader() {
System.out.println("主节点:" + judgeLeader);
client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL)
.forPath(Constants.judge_path, (judgeLeader+"_"+latch.getId()).getBytes());
}
public void notLeader() {
System.out.println("stop...");
}
});
latch.start();
} catch (Exception e) {
e.printStackTrace();
}
return latch;
}
}
创建客户端
/**
* @author guanzc
* @version 产品版本信息 Mar 19, 2020 姓名(邮箱) 修改信息
*/
package com.zk.server;
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.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class CuratorClientInitService {
@Value("${zookeeper.address}")
private String zk_address;
@Value("${zookeeper.timeout}")
private String timeout;
@Value("${zookeeper.maxRetries}")
private String maxRetries;
public CuratorFramework client = null;
public CuratorFramework getCuratorFrameworkClient() {
if (client != null) {
return client;
}
RetryPolicy retryPolicy = new ExponentialBackoffRetry(Integer.valueOf(timeout), Integer.valueOf(maxRetries));
client = CuratorFrameworkFactory.newClient(zk_address, retryPolicy);
client.start();
return client;
}
}
节点操作
/**
* @author guanzc
* @version 产品版本信息 Mar19, 2020 姓名(邮箱) 修改信息
*/
package com.zk.server;
import com.zk.config.Constants;
import com.zk.model.NodeModel;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.data.Stat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
@Service
public class ZookeeperApiService {
@Autowired
private CuratorClientInitService curatorClientInitService;
private CuratorFramework client = null;
@PostConstruct
public void initClient() {
if (client == null) {
client = curatorClientInitService.getCuratorFrameworkClient();
}
}
//创建节点
public String createNode(NodeModel nodeModel) {
String message = "";
try {
if (this.existsNode(nodeModel.getNodePath())) {
message = nodeModel.getNodePath() + " 节点已存在";
} else {
if (StringUtils.isEmpty(nodeModel.getNodeData())) {
if (nodeModel.isIsrecursion()) {
client.create().creatingParentsIfNeeded().forPath(Constants.base_path + nodeModel.getNodePath());
} else {
client.create().forPath(Constants.base_path + nodeModel.getNodePath());
}
} else {
if (nodeModel.isIsrecursion()) {
client.create().creatingParentsIfNeeded().forPath(Constants.base_path + nodeModel.getNodePath(), nodeModel.getNodeData().getBytes());
} else {
client.create().forPath(Constants.base_path + nodeModel.getNodePath(), nodeModel.getNodeData().getBytes());
}
}
message = nodeModel.getNodePath() + " 节点創建成功";
}
} catch (Exception e) {
e.printStackTrace();
}
return message;
}
//查询节点值
public String getNodeData(String path) {
String message = "";
try {
if (!this.existsNode(path)) {
message = "节点不存在";
} else {
message = new String(client.getData().forPath(Constants.base_path + path));
}
} catch (Exception e) {
e.printStackTrace();
}
return message;
}
//查询节点子节点以及值
public List<NodeModel> getChildList(String path) {
List<NodeModel> list = new ArrayList<NodeModel>();
try {
if (!this.existsNode(path)) {
return list;
} else {
NodeModel pnodeModel = new NodeModel();
pnodeModel.setNodePath(path);
pnodeModel.setNodeData(new String(client.getData().forPath(Constants.base_path + path)));
list.add(pnodeModel);
List<String> childList = client.getChildren().forPath(Constants.base_path + path);
for (String child : childList) {
String childPath = path + "/" + child;
if (this.existsNode(childPath)) {
NodeModel nodeModel = new NodeModel();
String data = new String(client.getData().forPath(Constants.base_path + childPath));
nodeModel.setNodeData(data);
nodeModel.setNodePath(childPath);
list.add(nodeModel);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
//删除节点值
public String deleteNode(String path) {
try {
if (this.existsNode(path)) { client.delete().deletingChildrenIfNeeded().forPath(Constants.base_path + path);
return "删除成功";
} else {
return "节点不存在";
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//修改节点值
public String updataNodePath(NodeModel nodeModel) {
try {
if (this.existsNode(nodeModel.getNodePath())) {
client.setData().forPath(Constants.base_path + nodeModel.getNodePath(), nodeModel.getNodeData().getBytes());
return "修改成功";
} else {
return "修改失败";
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//节点判断
private boolean existsNode(String path) {
try {
Stat stat = client.checkExists().forPath(Constants.base_path + path);
if (stat == null) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
}