zookeeper java代码实现master 选举
1,master选举使用场景及结构
现在很多时候我们的服务需要7*24小时工作,假如一台机器挂了,我们希望能有其它机器顶替它继续工作。此类问题现在多采用master-salve模式,也就是常说的主从模式,正常情况下主机提供服务,备机负责监听主机状态,当主机异常时,可以自动切换到备机继续提供服务(这里有点儿类似于数据库主库跟备库,备机正常情况下只监听,不工作),这个切换过程中选出下一个主机的过程就是master选举。
对于以上提到的场景,传统的解决方式是采用一个备用节点,这个备用节点定期给当前主节点发送ping包,主节点收到ping包后会向备用节点发送应答ack,当备用节点收到应答,就认为主节点还活着,让它继续提供服务,否则就认为主节点挂掉了,自己将开始行使主节点职责。如图1所示:
2,master 选择策略和zookeeper 分布式锁的思路大致一样
package com.aiyuesheng.controller; import java.util.concurrent.CountDownLatch; import org.I0Itec.zkclient.IZkDataListener; import org.I0Itec.zkclient.ZkClient; import org.I0Itec.zkclient.exception.ZkException; import org.I0Itec.zkclient.exception.ZkInterruptedException; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @Component public class MyApplicationRunner implements ApplicationRunner { private CountDownLatch countDownLatch = null; String PATH = "/master"; @Value("${server.port}") private String serverPort; ZkClient zkClient = new ZkClient("127.0.0.1:2181"); @Override public void run(ApplicationArguments args) throws Exception { System.out.println("初始化........."); // 2,zookeeper实现监听功能,当主节点挂了之后,继续选举 if (zkClient != null) { // 1,在初始化过程中创建一个临时节点,如果成功,则选为master节点 election(); // zookeeper 数据监听的接口 IZkDataListener izkDataListener = new IZkDataListener() { public void handleDataChange(String arg0, Object arg1) throws Exception { } public void handleDataDeleted(String path) throws Exception { // 一直在监听,节点有变化的时候原子量就是-1 if (countDownLatch != null) { countDownLatch.countDown(); } } }; //zkClient会去监听 zkClient.subscribeDataChanges(PATH, izkDataListener); if (zkClient.exists(PATH)) { countDownLatch = new CountDownLatch(1); try { // 一直进行等待,等待监听的路径有变化 countDownLatch.await(); election(); } catch (Exception e) { e.printStackTrace(); } } // 删除监听 zkClient.unsubscribeDataChanges(PATH, izkDataListener); } } private void election() { try { zkClient.createEphemeral(PATH, serverPort); System.out.println("选举成功"); ZookeeperMaster.masterIsAlive = true; } catch (Exception e) { ZookeeperMaster.masterIsAlive = false; } } }
public class ZookeeperMaster { public static boolean masterIsAlive = false; }
Aimer,c'est partager