2019独角兽企业重金招聘Python工程师标准>>>
public class FindLeader implements Watcher {
ZooKeeper zk;
static String ip = "";// 本机ip ,参数传过来的
RedisClient client;
String localName = "";// 本地创建zookeeper 递增节点后的名字
boolean isDead = false;// 用于监控redis连接的,如果连接断掉了则退出应用
public FindLeader() throws KeeperException, IOException,
InterruptedException {
zk = new ZooKeeper(
"192.168.93.128:2181,192.168.93.129:2181,192.168.93.130:2181",
3000, this);
client = RedisClient.getInstance(ip.split(":")[0], 6379);
}
/**
* @param args
*/
public static void main(String[] args) {
try {
ip = args[0].toString();
FindLeader find = new FindLeader();
find.run();
} catch (KeeperException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void process(WatchedEvent event) {
System.out.println("已经触发了" + event.getType() + "事件!" + " " + ip);
findLeader();
}
private void following(String leader) {
try {
List list = zk.getChildren("/group", false);
String[] nodes = list.toArray(new String[list.size()]);
Arrays.sort(nodes);
String first = nodes[0];
String masterIp = new String(zk.getData("/group/" + nodes[0],
false, null));
String watchIp = "";
// 查找比自己小的follower
// 并且监控他是否存在,因为选举master是根据最小的选举,这样,如果比自己小的挂掉了,那就是自己当master了
if (nodes.length == 1) {
watchIp = first;
} else {
for (int i = 0; i < nodes.length; i++) {
if (("/group/" + nodes[i]).equals(localName) && i != 0) {
watchIp = nodes[i - 1];
}
}
}
if (!watchIp.equals("")) {
zk.exists("/group/" + watchIp, true);
}
if (masterIp.equals(ip)) {
client.slaveOfNo();
}
for (int i = 1; i < nodes.length; i++) {
RedisClient c = RedisClient.getInstance(new String(zk.getData("/group/" + nodes[i], false, null)).split(":")[0], 6379);
c.setSlaveOf(masterIp.split(":")[0], 6379);
}
System.err.println("leader is :" + first);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (RedisOperationException e) {
e.printStackTrace();
}
}
private void findLeader() {
try {
System.err.println("执行查找master任务");
byte[] localhost = ip.getBytes();
if (localName.equals("")) {
localName = zk.create("/group/member_", localhost,ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
}
following(localName);
} catch (Exception e) {
e.printStackTrace();
}
}
private void run() {
while (!isDead) {
try {
if (!client.ping().equals("PONG")) {
isDead = true;
System.exit(2);
}
Thread.sleep(5000);
} catch (RedisOperationException e) {
e.printStackTrace();
isDead = true;
System.exit(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这两天学习了下zookeeper,顺便练习了下,用zookeeper实现了一个redis的主从,只是建了3个虚拟机,在虚拟机里跑了下测试没有问题,没有经过正式环境的考验,有些需要在优化的,欢迎吐槽