本文只介绍如何整合ZooKeeper,不会过多演示和讲解API,对于Zookeeper的专题介绍,请查看我的Zookeeper专栏
创建项目
1.pom.xml引入依赖
org.apache.curator
curator-recipes
4.0.1
2.配置文件
zk.url = 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
zk.timeout = 3000
3.ZookeeperConfig配置类
@Configuration
public class ZookeeperConfig {
@Value("${zk.url}")
private String zkUrl;
@Bean
public CuratorFramework getCuratorFramework(){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
CuratorFramework client = CuratorFrameworkFactory.newClient(zkUrl,retryPolicy);
client.start();
return client;
}
}
4.zookeeper封装工具类
public interface CRUDService {
boolean create(String path);
/**
* 给指定的ZNode设置值,不能嵌套创建目录
* 如果节点已经存在,会抛异常org.apache.zookeeper.KeeperException$NodeExistsException: KeeperErrorCode = NodeExists for /path
*/
boolean create(String path, byte[] payload);
/**
* 创建临时节点
* 需要注意:虽说临时节点是session失效后立刻删除,但是并不是client一断开连接,session就立刻会失效
* 失效是由zk服务端控制的,每次连接时,客户端和服务端会协商一个合理的超时时间
* 如果超过了超时时间client都一直美哦与发送心跳,才回真的删除这个session创建的临时节点
*/
boolean createEphemeral(String path, byte[] payload);
String createEphemeralSequential(CuratorFramework client, String path, byte[] payload) throws Exception;
/**
* 检查某个节点是否存在
*/
Stat Exists(String path);
/**
* 获取节点数据
*/
String getData(String path);
/*
*
* 设置节点数据
*/
boolean setData(String path);
boolean setDataAsync(String path, byte[] payload);
boolean setDataAsyncWithCallback(BackgroundCallback callback, String path, byte[] payload);
/**
* 查询子节点
*/
List getChildren(String path);
List watchedGetChildren(CuratorFramework client, String path);
List watchedGetChildren(CuratorFramework client, String path, Watcher watcher);
/**
* 删除节点
*/
boolean delete(CuratorFramework client, String path);
/**
* 删除一个节点,强制保证删除
*/
boolean guaranteedDelete(CuratorFramework client, String path);
}
@Service
public class CRUDServiceImpl implements CRUDService {
private static final Logger logger = LoggerFactory.getLogger(CRUDServiceImpl.class);
@Autowired
CuratorFramework curatorFramework;
public boolean create(String path){
try
{
curatorFramework.create().forPath(path);
return true;
}catch (Exception ex)
{
logger.error("【创建节点失败】{},{}",path,ex);
return false;
}
}
public boolean create(String path, byte[] payload){
try
{
curatorFramework.create().forPath(path, payload);
return true;
}catch (Exception ex)
{
logger.error("【创建节点失败】{},{}",path,ex);
return false;
}
}
public boolean createEphemeral(String path, byte[] payload) {
try
{
curatorFramework.create().withMode(CreateMode.EPHEMERAL).forPath(path, payload);
return true;
}catch (Exception ex)
{
logger.error("【创建节点失败】{},{}",path,ex);
return false;
}
}
public String createEphemeralSequential(CuratorFramework client, String path, byte[] payload) {
try
{
return client.create().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path, payload);
}
catch (Exception ex)
{
logger.error("【创建节点存在异常】{},{}",path,ex);
return null;
}
}
public Stat Exists(String path){
try
{
Stat stat = curatorFramework.checkExists().forPath(path);
return stat;
}
catch (Exception ex)
{
logger.error("【查看指定节点是否存在异常】{},{}",path,ex);
return null;
}
}
public String getData(String path) {
try
{
return new String(curatorFramework.getData().forPath(path));
}
catch (Exception ex)
{
logger.error("【获取节点数据异常】{},{}",path,ex);
return null;
}
}
public boolean setData(String path){
try {
curatorFramework.setData().forPath(path);
return true;
}
catch (Exception ex)
{
logger.error("【设置节点值异常】{},{}",path,ex);
return false;
}
}
public boolean setDataAsync(String path, byte[] payload) {
try {
CuratorListener listener = new CuratorListener() {
@Override
public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception {
if (event != null)
System.out.println(event.toString());
}
};
curatorFramework.getCuratorListenable().addListener(listener);
curatorFramework.setData().inBackground().forPath(path, payload);
return true;
}
catch (Exception ex)
{
logger.error("【设置节点值异常】{},{}",path,ex);
return false;
}
}
public boolean setDataAsyncWithCallback(BackgroundCallback callback, String path, byte[] payload){
try
{
curatorFramework.setData().inBackground(callback).forPath(path, payload);
return true;
}
catch (Exception ex)
{
logger.error("【设置节点值异常】{},{}",path,ex);
return false;
}
}
public List getChildren(String path) {
try
{
return curatorFramework.getChildren().forPath(path);
}
catch (Exception ex)
{
logger.error("【查询指定子节点异常】{},{}",path,ex);
return null;
}
}
public List watchedGetChildren(CuratorFramework client, String path) {
try
{
return client.getChildren().watched().forPath(path);
}
catch (Exception ex)
{
logger.error("【查询指定子节点异常】{},{}",path,ex);
return null;
}
}
public List watchedGetChildren(CuratorFramework client, String path, Watcher watcher){
try
{
return client.getChildren().usingWatcher(watcher).forPath(path);
}
catch (Exception ex)
{
logger.error("【查询指定子节点异常】{},{}",path,ex);
return null;
}
}
public boolean delete(CuratorFramework client, String path){
try
{
client.delete().forPath(path);
return true;
}
catch (Exception ex)
{
logger.error("【删除指定节点异常】{},{}",path,ex);
return false;
}
}
public boolean guaranteedDelete(CuratorFramework client, String path) {
try
{
client.delete().guaranteed().forPath(path);
return true;
}
catch (Exception ex)
{
logger.error("【删除指定节点异常】{},{}",path,ex);
return false;
}
}
}