package com.autonavi.tinfo.t1.traffic.pub.openlr.util;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.zkclient.IZkChildListener;
import com.github.zkclient.IZkStateListener;
import com.github.zkclient.ZkClient;

public class StatusMonitor {

private Lock lock = new ReentrantLock();// 锁对象
    private boolean usingHA = true;
    private volatile boolean isLeader = false;

private static final Logger logger = LoggerFactory.getLogger(StatusMonitor.class);
    // 超时时间
    private int zkSessionTimeOut=5000;
    private int zkConnectionTimeOut=5000;
    //private int SESSION_TIMEOUT = 5000;
    //private int CONNECTION_TIMEOUT = 5000;

// zookeeper server列表
    private String zkServerList = "10.17.132.71:2181";

private String zkServerDir = "fast-update";
    private String subNode = "openlr";

// 当前client创建的子节点
    private String curPath;
    private ZkClient zkClient;
    ScheduledExecutorService intervalMonitorExecutor = Executors.newSingleThreadScheduledExecutor();

/**
     * 连接zookeeper
     */
    public void init() {
        logger.info("StatusMonitor.init zkSessionTimeOut:{},zkConnectionTimeOut:{}",zkSessionTimeOut,zkConnectionTimeOut);
        try {
            connect();
        } catch (Exception e) {
            this.isLeader = false;
            logger.error(e.getMessage(), e);
            try {
                connect();
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                logger.error("error occurs during sync data from zk");
                System.exit(0);
            } finally {
                ;
            }
        }

intervalMonitorExecutor.scheduleAtFixedRate(new Runnable() {

@Override
            public void run() {
                lock.lock();
                try {
                    if (zkClient == null) {
                        isLeader = false;
                        return;
                    }
                    if (zkClient != null && zkClient.getZooKeeper() == null) {
                        isLeader = false;
                        return;
                    }
                    if (zkClient != null && (!zkClient.getZooKeeper().getState().isAlive()
                            || !zkClient.getZooKeeper().getState().isConnected())) {
                        isLeader = false;
                        return;
                    }
                } finally {
                    lock.unlock();
                }
            }
        }, 0, 2, TimeUnit.SECONDS);

}

public void connect() throws Exception {
        if (!usingHA) {
            return;
        }

if (this.zkClient != null) {
            this.zkClient.close();
        }
        this.zkClient = new ZkClient(zkServerList, zkSessionTimeOut, zkConnectionTimeOut);

if (!zkClient.exists("/" + zkServerDir)) {
            zkClient.createPersistent("/" + zkServerDir, null);
        }
        if (curPath == null) {
            curPath = zkClient.createEphemeralSequential("/" + zkServerDir + "/" + subNode, "monitor".getBytes());
        }

try {
            startWatchingTopicStatus();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            logger.error(e.getMessage(), e);
            logger.error("error occurs during sync data from zk");
            System.exit(0);
        }
        Thread.sleep(2000);// */
        handleMonitorNodeChange();
    }

public void startWatchingTopicStatus() {
        ZkTopicStatusListener topicEventListener = new ZkTopicStatusListener();
        ZkConnectedStatusListener connectedStatusListener = new ZkConnectedStatusListener();
        try {
            zkClient.subscribeChildChanges("/" + zkServerDir, topicEventListener);
            zkClient.subscribeStateChanges(connectedStatusListener);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            startWatchingTopicStatus();
        }

}

public void stop() {
        if (zkClient == null) {
            logger.warn("shutdown topic event watcher");
            return;
        }
        // stopWatchingTopicEvents();
        zkClient.close();
        zkClient = null;
    }

private void beLeader() {
        logger.info("this node gains lock {} and becomes leader ", curPath);
        System.out.println("this node gains lock " + curPath + " and becomes leader");
        this.isLeader = true;
    }

public void setUsingHA(boolean isUsingHA) {
        this.usingHA = isUsingHA;
    }

public void setZkServerDir(String zkServerDir) {
        this.zkServerDir = zkServerDir;
    }

public boolean isUsingHA() {
        return usingHA;
    }

public boolean isLeader() {
        return isLeader;
    }

public void setZkServerList(String zkServerList) {
        this.zkServerList = zkServerList;
    }

/*public int getSESSION_TIMEOUT() {
        return SESSION_TIMEOUT;
    }

public void setSESSION_TIMEOUT(int sESSION_TIMEOUT) {
        SESSION_TIMEOUT = sESSION_TIMEOUT;
    }

public int getCONNECTION_TIMEOUT() {
        return CONNECTION_TIMEOUT;
    }

public void setCONNECTION_TIMEOUT(int cONNECTION_TIMEOUT) {
        CONNECTION_TIMEOUT = cONNECTION_TIMEOUT;
    }*/

public int getZkSessionTimeOut() {
        return zkSessionTimeOut;
    }

public void setZkSessionTimeOut(int zkSessionTimeOut) {
        this.zkSessionTimeOut = zkSessionTimeOut;
    }

public int getZkConnectionTimeOut() {
        return zkConnectionTimeOut;
    }

public void setZkConnectionTimeOut(int zkConnectionTimeOut) {
        this.zkConnectionTimeOut = zkConnectionTimeOut;
    }

public void handleMonitorNodeChange() throws Exception {
        this.lock.lock();
        try {
            if (zkClient == null)
                return;
            if (!zkClient.exists("/" + zkServerDir)) {
                zkClient.createPersistent("/" + zkServerDir, null);
            }

// 确认curPath是否真的是列表中的最小节点
            List<String> childs = zkClient.getChildren("/" + zkServerDir);
            if (childs == null || childs.size() == 0) {
                // 创建子节点
                curPath = zkClient.createEphemeralSequential("/" + zkServerDir + "/" + subNode, "monitor".getBytes());
                childs = zkClient.getChildren("/" + zkServerDir);
            }
            Collections.sort(childs);

String thisNode = curPath.substring(("/" + zkServerDir + "/").length());
            int index = childs.indexOf(thisNode);
            if (index < 0) {
                curPath = zkClient.createEphemeralSequential("/" + zkServerDir + "/" + subNode, "monitor".getBytes());
                childs = zkClient.getChildren("/" + zkServerDir);
                Collections.sort(childs);
                thisNode = curPath.substring(("/" + zkServerDir + "/").length());
                index = childs.indexOf(thisNode);
            }

if (index == 0) {
                // 确实是最小节点
                beLeader();
            } else {
                this.isLeader = false;
            }
        } finally {
            this.lock.unlock();
        }
    }

class ZkTopicStatusListener implements IZkChildListener {

@Override
        public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
            handleMonitorNodeChange();
        }
    }

class ZkConnectedStatusListener implements IZkStateListener {

@Override
        public void handleStateChanged(KeeperState state) throws Exception {
            // TODO Auto-generated method stub
            if (state.equals(state.SyncConnected) || state.equals(state.ConnectedReadOnly)) {
                System.out.println("zookeeper start to be connected");
                handleMonitorNodeChange();
            }
        }

@Override
        public void handleNewSession() throws Exception {
            // TODO Auto-generated method stub
        }

}

public static void main(String[] args) throws Exception {
        StatusMonitor statusMonitor = new StatusMonitor();
        statusMonitor.setZkServerList("10.61.97.23:2181");
        statusMonitor.setUsingHA(true);

statusMonitor.init();

Thread.sleep(100000000);
    }

}

zk抢主的更多相关文章

  1. Zookeeper笔记之使用zk实现集群选主

    一.需求 在主从结构的集群中,我们假设硬件机器是很脆弱的,随时可能会宕机,当master挂掉之后需要从slave中选出一个节点作为新的master,使用zookeeper可以很简单的实现集群选主功能. ...

  2. zookeeper分布式服务中选主的应用

    通常zookeeper在分布式服务中作为注册中心,实际上它还可以办到很多事.比如分布式队列.分布式锁 由于公司服务中有很多定时任务,而这些定时任务由于一些历史原因暂时不能改造成框架调用 于是想到用zo ...

  3. zookeeper典型应用场景之一:master选举

    对于zookeeper这种东西,仅仅知道怎么安装是远远不够的,至少要对其几个典型的应用场景进行了解,才能比较全面的知道zk究竟能干啥,怎么玩儿,以后的日子里才能知道这货如何能为我所用.于是,有了如下的 ...

  4. Zookeeper客户端Curator的使用,简单高效

    Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量. 1.引入依赖: ...

  5. zookeeper选举机制

    在上一篇文章中我们大致浏览了zookeeper的启动过程,并且提到在Zookeeper的启动过程中leader选举是非常重要而且最复杂的一个环节.那么什么是leader选举呢?zookeeper为什么 ...

  6. ZooKeeper 典型应用场景-Master选举

    master选举 1.使用场景及结构 现在很多时候我们的服务需要7*24小时工作,假如一台机器挂了,我们希望能有其它机器顶替它继续工作.此类问题现在多采用master-salve模式,也就是常说的主从 ...

  7. zookeeper master 选举

    原文地址: http://www.cnblogs.com/nevermorewang/p/5611807.html 选主原理介绍:zookeeper的节点有两种类型,持久节点跟临时节点.临时节点有个特 ...

  8. zookeeper 笔记--curator分布式锁

    使用ZK实现分布式独占锁, 原理就是利用ZK同级节点的唯一性. Curator框架下的一些分布式锁工具InterProcessMutex:分布式可重入排它锁 InterProcessSemaphore ...

  9. 大数据学习(22)—— ZooKeeper能做些什么

    官网上已经给出了zk的几种典型应用场景,原话是这么说的: It exposes a simple set of primitives that distributed applications can ...

随机推荐

  1. warning: incompatible implicit declaration of built-in function ‘exit’

    出现这个错误,一般是程序中某个函数没有include相关的文件. EG. 出现这个错误是因为要使用exit()应该包含stdlib.h文件

  2. 谷歌浏览器中安装.crx扩展名的离线Chrome插件

    一.本地拖放安装 1.下载扩展程序/脚本程序至本地计算机: 2.将其直接拖拽到浏览器的“扩展程序”(chrome://chrome/extensions/)页面. 二.解决“只能通过Chrome网上应 ...

  3. 2014年5月份第1周51Aspx源码发布详情

    郑州某高校学生考评系统源码  2014-5-5 [VS2008]功能介绍:   1.用户角色有部主任.教师.学生等.   2.可添加班级考评项目.学生考评项目.   3.可指定学生对班级.学生某考评项 ...

  4. UE4 在C++ 动态生成几何、BSP体、Brush ---- Mesh_Generation

    截至UE4  4.10 runtime 无法生成BSP类 ,只能通过自定义的Mesh的Vertex 进行绘制 ( Google 考证,能改UE4源码的请忽略 ) 可用到的 UE4 集成的Render ...

  5. PHP flush sleep 输出缓存控制详解

    1 2 3 4 5 6 ob_start,flush,ob_flush for($i=0;$i<</SPAN>10;$i++) { echo $i.''; flush(); slee ...

  6. 1、webservice的简单使用

    1.新建一个web端项目 2.点击添加项,选择web服务 3.在已经建好的项目中写一个方法 4.发布(发布方法选文件系统,web需要管理员权限) 生成文件夹: 5.配置IIS(略) 6.调用webse ...

  7. HTTP通信原理

    HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则.计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器(Web服务器)请求 ...

  8. Collection(数组、字典、集合)

    Collection     -NSArray和NSMutableArray         +array:创建一个空数组         +arrayWithArray:从另一个数组创建新的数组   ...

  9. raw_input 和input的区别

    input它会根据用户输入变换相应的类型, raw_input则是不管用户输入什么类型的都会转变成字符型.

  10. maven docker 操作

    1. 使用dokerfile 进行构建 创建dockerfile 2. maven 插件 <plugin> <groupId>com.spotify</groupId&g ...