springboot 集成zookeeper

介绍

curator对zookeeper 进行了封装,提供了强大API,介绍下对节点常用操作

导入依赖

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-client</artifactId>
    <version>2.13.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>2.13.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.13.0</version>
</dependency>
<dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <version>1.18.4</version>
</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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值