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 ...
随机推荐
- Android 绿豆蛙版连连看(简陋版)
(里面有六张绿豆蛙的图片) 1.选中会有红色框 2.可以直线连(横竖相邻或是横竖间隔空格) 3.可以拐一次弯连接 4.可以拐两次弯连接 5.连接时会有线显示 6.绿色代表进度条,蓝色代表时间条 imp ...
- 团队开发——冲刺2.d
冲刺阶段二(第四天) 1.昨天做了什么? 把收集的图标进行统一整理,使用相同风格.类型,使界面更加美观. 2.今天准备做什么? 开始写测试计划书. 3.遇到什么困难? 关于昨天遇到的问题:在游戏界面加 ...
- 第十三周学习笔记(编辑器选错了重发了这一个 原博客的确周天晚上提交了orz)
并发:逻辑控制流在时间上的重叠. 构造并发程序的方法: 进程 I/O多路复用 线程 基于进程的并发编程 假设我们有两个客户端和一个服务器,服务器正在监听一个监听表述符上的请求.现在假设服务器接受了客户 ...
- Flume 实战(1) -- 初体验
前言: Flume-ng是数据收集/聚合/传输的组件, Flume-ng抛弃了Flume OG原本繁重的zookeeper和Master, Collector, 其整体的架构更加的简洁和明了. 其基础 ...
- Node.js高级编程读书笔记 - 3 网络编程
Outline 3.4 构建TCP服务器 3.5 构建HTTP服务器 3.6 构建TCP客户端 3.7 创建HTTP请求 3.8 使用UDP 3.9 用TLS/SSL保证服务器的安全性 3.10 用H ...
- Candy Store
Candy Store Time Limit: 30000ms, Special Time Limit:75000ms, Memory Limit:65536KB Total submit users ...
- Smarty 分页
1 <div id="pagelist" class="clearfix">2 <a href="/canadian-sai ...
- kafka2.9.2的伪分布式集群安装和demo(java api)测试
目录: 一.什么是kafka? 二.kafka的官方网站在哪里? 三.在哪里下载?需要哪些组件的支持? 四.如何安装? 五.FAQ 六.扩展阅读 一.什么是kafka? kafka是LinkedI ...
- [转]js中的字符串函数集和代码片段
JS自带函数 concat将两个或多个字符的文本组合起来,返回一个新的字符串.var a = "hello";var b = ",world";var c = ...
- Nginx 负载均衡学习
nginx作为负载均衡服务器,用户请求先到达nginx,再由nginx根据负载配置将请求转发至 tomcat服务器. nginx负载均衡服务器 tomcat1服务器 tomcat2服务器 1.1 ...