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<String> 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个虚拟机,在虚拟机里跑了下测试没有问题,没有通过正式环境的考验,有些须要在优化的,欢迎吐槽java