zk抢主
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抢主的更多相关文章
- Zookeeper笔记之使用zk实现集群选主
一.需求 在主从结构的集群中,我们假设硬件机器是很脆弱的,随时可能会宕机,当master挂掉之后需要从slave中选出一个节点作为新的master,使用zookeeper可以很简单的实现集群选主功能. ...
- zookeeper分布式服务中选主的应用
通常zookeeper在分布式服务中作为注册中心,实际上它还可以办到很多事.比如分布式队列.分布式锁 由于公司服务中有很多定时任务,而这些定时任务由于一些历史原因暂时不能改造成框架调用 于是想到用zo ...
- zookeeper典型应用场景之一:master选举
对于zookeeper这种东西,仅仅知道怎么安装是远远不够的,至少要对其几个典型的应用场景进行了解,才能比较全面的知道zk究竟能干啥,怎么玩儿,以后的日子里才能知道这货如何能为我所用.于是,有了如下的 ...
- Zookeeper客户端Curator的使用,简单高效
Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量. 1.引入依赖: ...
- zookeeper选举机制
在上一篇文章中我们大致浏览了zookeeper的启动过程,并且提到在Zookeeper的启动过程中leader选举是非常重要而且最复杂的一个环节.那么什么是leader选举呢?zookeeper为什么 ...
- ZooKeeper 典型应用场景-Master选举
master选举 1.使用场景及结构 现在很多时候我们的服务需要7*24小时工作,假如一台机器挂了,我们希望能有其它机器顶替它继续工作.此类问题现在多采用master-salve模式,也就是常说的主从 ...
- zookeeper master 选举
原文地址: http://www.cnblogs.com/nevermorewang/p/5611807.html 选主原理介绍:zookeeper的节点有两种类型,持久节点跟临时节点.临时节点有个特 ...
- zookeeper 笔记--curator分布式锁
使用ZK实现分布式独占锁, 原理就是利用ZK同级节点的唯一性. Curator框架下的一些分布式锁工具InterProcessMutex:分布式可重入排它锁 InterProcessSemaphore ...
- 大数据学习(22)—— ZooKeeper能做些什么
官网上已经给出了zk的几种典型应用场景,原话是这么说的: It exposes a simple set of primitives that distributed applications can ...
随机推荐
- python3+任务计划实现的人人影视网站自动签到
python3+任务计划实现的人人影视网站自动签到 这是一个自动化程度较高的程序,运行本程序后会从chrome中读取cookies用于登录人人影视签到, 并且会自动添加一个windows 任务计划,这 ...
- ACM 矩阵题目整理
先从最基础的矩阵快速幂加速递推开始. HDU 1005 Number Sequence |f[n-2],f[n-1]|* |0 B| =|f[n-1], B*f[n-2]+A*f[n-1]|=|f[n ...
- segues的类型
Name Interface Builder symbol Description Show Present the content in the detail or master area depe ...
- .Net MVC框架 + WCF 搭建 集群开发
http://www.cnblogs.com/zhijianliutang/archive/2012/01/28/2258844.html
- GCD的基本知识
什么是GCD 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自 ...
- IOS7.0 Xcode5 AutoLayout 备忘录
Xcode5 xib设置autolayout方式: 列表1: (选择两个view时可设置) 左边对齐, 右边对齐, 顶部对齐, 底部对齐, x轴中心对齐, y轴中心对齐, 文本底标线对齐, (单选择一 ...
- <转>两个蛋蛋的故事
来自为知笔记(Wiz)
- PAT (Basic Level) Practise:1030. 完美数列
[题目链接] 给定一个正整数数列,和正整数p,设这个数列中的最大值是M,最小值是m,如果M <= m * p,则称这个数列是完美数列. 现在给定参数p和一些正整数,请你从中选择尽可能多的数构成一 ...
- aptitude解决Ubuntu各种依赖问题
转自:http://allog.ml/linux/aptitude%E8%A7%A3%E5%86%B3ubuntu%E5%90%84%E7%A7%8D%E4%BE%9D%E8%B5%96%E9%97% ...
- 2017.1.8a版给信息源新增:max_len、max_db字段
2017.1.8a版程序给信息源增加max_len.max_db字段,分别用于控制:获取条数.数据库保留条数. max_len的说明见此图: max_db的说明见此图: 当max_len和max_db ...