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. Android GridView的使用

    Android的GridView控件用于把一系列的空间组织成一个二维的网格显示出来应用的比较多的就是组合图片显示下面我就详细讲一个例子 首先写一个类继承BaseAdapter 1. Java代码 1 ...

  2. Unity3D 使用C#指针unsafe

    Unsafe code requires the `unsafe' command line option to be specified 在Unity开发中,如果涉及到指针的使用,需要自己定义预处理 ...

  3. 修改FastColoredTextBox控件完成选择

    //判断是否是中文        public bool IsChina(char c)        { bool BoolValue = false;            if (Convert ...

  4. block的语法

    主要内容: 1. 开始使用block(Getting Started with Blocks) 2. block概念综述(Conceptual Overview) 3. 声明和创建block(Decl ...

  5. 用python+selenium将腾讯首页今日话题的内容自动发表到自己cnblog里

    目的:使用pyhton下的unittest单元测试框架并结合selenium的webdriver来实现将腾讯首页的今日话题下的内容自动发表达到自己的cnblog里. 思路:创建QQDailyTopic ...

  6. python-内置函数、装饰器

    本节内容:一之前课程回顾: 在书写代码的时候,先写简单的逻辑在写复杂的逻辑.概念梳理:1.函数在传递实参的时候是传递的是引用而不是从内存中重新赋相同值给形参.比如: def test(x): x.ap ...

  7. (实用篇)PHP中单引号与双引号的区别分析

    在PHP中,我们可以使用单引号或者双引号来表示字符串.不过我们作为开发者,应该了解其中的区别.单引号与双引号对于定义字符一个是可以解析变量一个是会把变量直接输出来,同时单引号与双引号在字符处理上单引号 ...

  8. ✡ leetcode 163. Missing Ranges 找出缺失范围 --------- java

    Given a sorted integer array where the range of elements are in the inclusive range [lower, upper], ...

  9. Bank,我只是来完成作业的

    写这个Bank我需要有:开户,取款,存款,转账,查询余额,退出功能. 这样我需要有两个类:Bank,User.一个Main入口. 先看这个User,他定义了各个需要的属性(字段)和字段的属性(虽然在这 ...

  10. Event List 2

    The list of events can be found in src/switch_event.c in a char array called EVENT_NAMES and is summ ...