2021最新zookeeper系列
❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️
Ⅰ:zookeeper的单机安装 - 详细教程:https://blog.csdn.net/Kevinnsm/article/details/116134397?spm=1001.2014.3001.5501
Ⅱ:zookeeper的相关shell命令:https://blog.csdn.net/Kevinnsm/article/details/116137602?spm=1001.2014.3001.5501
Ⅲ:zookeeper之查看节点的状态信息:https://blog.csdn.net/Kevinnsm/article/details/116143218?spm=1001.2014.3001.5501
Ⅳ:zookeeper的acl权限控制:https://blog.csdn.net/Kevinnsm/article/details/116167394?spm=1001.2014.3001.5501
Ⅴ:zookeeper的相关Java Api:https://blog.csdn.net/Kevinnsm/article/details/116462557?spm=1001.2014.3001.5501
Ⅵ:zookeeper的Watcher事件监听机制:https://blog.csdn.net/Kevinnsm/article/details/116501842?spm=1001.2014.3001.5501
Ⅶ:教你一招利用zookeeper作为服务的配置中心:https://blog.csdn.net/Kevinnsm/article/details/116542974?spm=1001.2014.3001.5501
❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️
1、连接zookeeper服务器
2、连接时必须使当前线程等待(等待其他线程创建连接zookeeper服务成功,使用计数器实现)
3、执行回调函数process
4、释放当前线程
演示mysql的连接配置(将mysql连接属性配置到zookeeper服务器)
使用云服务器作为zookeeper的演示环境,本地使用xshell远程连接
如果不知,请移步:https://blog.csdn.net/Kevinnsm/article/details/116134397?spm=1001.2014.3001.5501
create /config “config”
create /config/mysql “datasource”
create /config/mysql/driver "com.mysql.cj.jdbc.Driver
create /config/mysql/url "jdbc:mysql://127.0.0.1/test?serverTimezone=UTC
create /config/mysql/username “root”
create /config/mysql/password “xxxxxxx”
package com.zookeeper.config;
import com.zookeeper.watcher.WatcherConnection;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Test;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @author:抱着鱼睡觉的喵喵
* @date:2021/5/8
* @description:
*/
public class ZookeeperConfigCenter implements Watcher {
//mysql的本地变量
private String driver;
private String url;
private String username;
private String password;
static ZooKeeper zooKeeper;
static CountDownLatch countDownLatch = new CountDownLatch(1);
final static String IP = "8.140.37.103:2181";
//构造函数,只要一创建该类,就执行getProperty()方法
public ZookeeperConfigCenter() {
getProperty();
}
//重写回调函数
@Override
public void process(WatchedEvent watchedEvent) {
try {
if (watchedEvent.getType() == Event.EventType.None) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
System.out.println("连接成功");
//如果连接成功,放行当前线程
countDownLatch.countDown();
} else if (watchedEvent.getState() == Event.KeeperState.Disconnected) {
System.out.println("连接中断");
} else if (watchedEvent.getState() == Event.KeeperState.Expired) {
System.out.println("连接超时");
//如果连接超时就重新进行连接
zooKeeper = new ZooKeeper(IP, 5000, new WatcherConnection());
} else if (watchedEvent.getState() == Event.KeeperState.AuthFailed) {
System.out.println("验证失败");
}
//如果监听到节点数据发生了变化,就重新连接读取节点数据
} else if (watchedEvent.getType() == Event.EventType.NodeDataChanged) {
getProperty();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//核心方法
public void getProperty() {
try {
//连接zookeeper服务
zooKeeper = new ZooKeeper(IP, 20000, this);
//等待其他线程连接zookeeper服务
countDownLatch.await();
this.driver = new String(zooKeeper.getData("/config/mysql/driver", true, null));
this.url = new String(zooKeeper.getData("/config/mysql/url", true, null));
this.username = new String(zooKeeper.getData("/config/mysql/username", true, null));
this.password = new String(zooKeeper.getData("/config/mysql/password", true, null));
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
@Test
public void test() {
try {
ZookeeperConfigCenter configCenter = new ZookeeperConfigCenter();
for (int i = 1; i < 6; i++) {
System.out.println(configCenter.driver);
System.out.println(configCenter.url);
System.out.println(configCenter.username);
System.out.println(configCenter.password);
//休眠10秒
Thread.sleep(10000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
另外也用到了一个简单的连接类作为zookeeper连接超时的回调处,然后进性重新连接(实现了watcher接口)
public class WatcherConnection implements Watcher {
static CountDownLatch countDownLatch = new CountDownLatch(1);
//计数器
static ZooKeeper zooKeeper;
public static void main(String[] args) {
try {
zooKeeper = new ZooKeeper("123.57.252.59:2181", 5000, new WatcherConnection());
countDownLatch.await();
Thread.sleep(10000);
zooKeeper.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void process(WatchedEvent watchedEvent) {
try {
if (watchedEvent.getType() == Event.EventType.None) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
System.out.println("连接成功!");
countDownLatch.countDown();
} else if (watchedEvent.getState() == Event.KeeperState.Disconnected) {
System.out.println("断开连接");
} else if (watchedEvent.getState() == Event.KeeperState.Expired) {
System.out.println("超时了");
} else if (watchedEvent.getState() == Event.KeeperState.AuthFailed) {
System.out.println("认证失败!");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
可以看出当监听到/config/mysql/username节点的数据发生变更时,控制台就会重新获取节点值
如果控制台出现了ConnectionLoss错误,可能是网络差导致连接断开或者服务器宕机