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. <转>.php导出excel(多种方法)

    基本上导出的文件分为两种:1:类Excel格式,这个其实不是传统意义上的Excel文件,只是因为Excel的兼容能力强,能够正确打开而已.修改这种文件后再保存,通常会提示你是否要转换成Excel文件. ...

  2. Objective-C学习笔记-第二天(1)

    Objective-C中,调用方法采用的是一种消息传递机制. 参考文章:http://blog.csdn.net/xingyevc/article/details/39397873 如果向某个对象传递 ...

  3. BFC and Haslayout

    一.BFC(Block Formatting Context) 相关网址:http://www.cnblogs.com/dolphinX/p/3508869.html 1. 怎样才能形成BFC flo ...

  4. codeforces 446B(优先队列)

    题目链接:http://codeforces.com/problemset/problem/446/B #include<bits/stdc++.h> using namespace st ...

  5. JavaScript闭包学习笔记

    此文都是大牛们关于闭包的观点,在此只是总结. 闭包应用的两种情况即可——函数作为返回值,函数作为参数传递. 1 深入理解javascript原型和闭包 判断一个变量是不是对象非常简单.值类型的类型判断 ...

  6. B - Encoded Love-letter 字符串的处理

    B - Encoded Love-letter Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & % ...

  7. linux下安装mongodb(php版本5.3)

    转:原文出处忘记了. 1. 下载MongoDB 2. 解压文件到某目录下,然后重命名: [root@localhost var]# tar -xzvf mongodb-linux-i686-2.0.1 ...

  8. 1-Recyclerview使用系列之Recyclerview的列表数据显示

    使用步骤已经写到我的公众号,二维码在下面,欢迎关注,谢谢. 本人联系方式: 更多精彩分享,可关注我的微信公众号: 若想给予我分享更多知识的动力,请扫描下面的微信打赏二维码,谢谢!: 微信号:Weixi ...

  9. JavaScript对象属性赋值操作的逻辑

    对象进行属性赋值操作时,其执行逻辑如下所示: 1. 当前对象中是否有该属性?有,进行赋值操作:没有,进行下一步判断. 2. 对象的原型链中是否有该属性?没有,在当前对象上创建该属性,并赋值:有,进行下 ...

  10. UIKIT的简介

    // // UIKIT各框架的简介 // IOS笔记 // // Created by 刘威成 on 13/12/14. // Copyright © 2015年 刘威成. All rights re ...