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 ...
随机推荐
- 银光类似web visio的节点连线控件Essential Diagram免费下载地址
Essential Diagram for Silverlight是一款功能强大的图解拓扑图控件,在XAML支持的情况下提供用户交互式地创建和编辑图解,支持数据绑定和多种布局,可以导出为多种文件格式等 ...
- 团队开发——冲刺1.g
冲刺阶段一(第七天) 1.昨天做了什么? 整合界面设计与代码:测试程序. 2.今天准备做什么? A.测试程序,分析代码: B.把最初的内部测试版打包给用户体验,总结功能上的不足交予PM. 3.遇到什么 ...
- 在 Sublime Text 2 中使用 SFTP 插件快速编辑远程服务器文件
在 Sublime Text 2 中使用 SFTP 插件快速编辑远程服务器文件 开源程序 浏览:29555 2013年05月02日 文章目录[隐藏] 常见的工作流程 SFTP 安装和使用方法 第一步: ...
- NOSCRIPT标签的用处
NOSCRIPT标签用来定义在脚本未被执行时的替代内容.也可以用在检测浏览器是否支持脚本,若不支持脚本则可以显示NOSCRIPT标签里的innerText. eg:<body> ... . ...
- activity 和 生命周期 :流程
activity是android的一个基本的组件.讨论生命周期,taskstack等等的话题的时候.就不得不去看一下android framework层的源码了. 生命周期,实际就是系统调用andro ...
- angularjs 迭代器
angularjs 迭代器可以使用管道字符(|)添加到表达式和指令中. 有以下五种转换数据的迭代器: (1)currency-格式化数字为货币格式. (2)filter-从数组中选择一个一个子集. ( ...
- Hive 实战(2)--hive分区分桶实战
前言: 互联网应用, 当Mysql单机遇到性能瓶颈时, 往往采用的优化策略是分库分表. 由于互联网应用普遍的弱事务性, 这种优化效果非常的显著.而Hive作为数据仓库, 当数据量达到一定数量时, 查询 ...
- Jena对描述逻辑构造的支持
前言 本文依据"The Description Logic Handbookd"中Appendxi1 Description Terminology中基本的描述逻辑构造,考察Jen ...
- web安全之sql注入联合查询
联合查询的条件: 有显示位.当然要有注入点!! 提前需要了解的函数: union可合并两个或多个select语句的结果集,前提是两个select必有相同列.且各列的数据类型也相同 distinct 去 ...
- 大道至简---软件工程实践者的思想------------java伪代码形式读后感第一章
import.java.大道至简.*; 1.编程的精义----愚公移山 /* 原始需求的产生:惩山北之塞,出入之迂 项目沟通的基本方式:聚室而谋曰 项目的目标:毕力平险,指通豫南,达于汉阴 技术方案: ...