public interface ClusterLeaderListener {
public void gainLeader();
public void loserLeader();
}
public interface ClusterManager {
/**
* 获取leader节点
* @throws Exception
*/
void acquireLeader() throws Exception;
/**
* 关闭leader选举
* @throws Exception
*/
void closeLeaderLatch() throws Exception;
/**
* 开始leader选举
* @throws Exception
*/
void startLeaderLatch() throws Exception;
/**
* 添加监听器
* @throws Exception
*/
void addLeaderListener(ClusterLeaderListener listener) throws Exception;
}
/**
* 连接zookeeper服务器,leader选举
* @author hao.wang 2017年1月18日 下午5:29:44
*
*/
public class ZookeeperClusterManager implements ClusterManager{
private CuratorFramework framework;
private LeaderLatch leaderLatch;
private static List<ClusterLeaderListener> listeners = new ArrayList<ClusterLeaderListener>();
private volatile boolean isLeaderLatchStart = false;
private static final String DETAULE_ELECTION_PATH = "/election/demo/hao";
public ZookeeperClusterManager() {
framework= CuratorFrameworkFactory.newClient("139.199.182.26:5000",30000,5000,
new ExponentialBackoffRetry(2000,Integer.MAX_VALUE));
framework.start();
leaderLatch = new LeaderLatch(framework, DETAULE_ELECTION_PATH);
try {
leaderLatch.start();
} catch (Exception e) {
e.printStackTrace();
}
isLeaderLatchStart = true;
leaderLatch.addListener(new LeaderLatchListener() {
@Override
public void notLeader() {
synchronized(this){
if(!listeners.isEmpty()){
for (ClusterLeaderListener listener : listeners) {
listener.loserLeader();
}
}
}
}
@Override
public void isLeader() {
synchronized(this){
if(!listeners.isEmpty()){
for (ClusterLeaderListener listener : listeners) {
listener.gainLeader();
}
}
}
}
});
}
@Override
public void acquireLeader() throws Exception {
this.leaderLatch.await();
}
@Override
public void closeLeaderLatch() throws Exception {
this.leaderLatch.close();
}
@Override
public void startLeaderLatch() throws Exception {
if(!isLeaderLatchStart){
this.leaderLatch.start();
}
}
@Override
public void addLeaderListener(ClusterLeaderListener listener) throws Exception {
if(!this.listeners.contains(listener)){
listeners.add(listener);
}
}
}
public interface SchedulerBootstrap {
void start() throws Exception;
void stop() throws Exception;
}
public class SchedulerBootstrapImpl implements SchedulerBootstrap {
private String serverName;
private ClusterManager clusterManager = new ZookeeperClusterManager();
private volatile boolean shutDown = false;
public SchedulerBootstrapImpl(String serverName) {
this.serverName = serverName;
}
@Override
public void start() throws Exception {
if (shutDown) {
throw new RuntimeException("任务已经停止");
}
boolean leaderAcuqire = false;
while (!Thread.currentThread().isInterrupted()) {
try {
clusterManager.acquireLeader();
leaderAcuqire = true;
break;
} catch (Exception e) {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
return;
}
if (shutDown) {
return;
}
Thread.sleep(5000);
}
}
System.out.println(serverName + "获得处理权力,开始执行任务");
if (leaderAcuqire) {
startService();
}
clusterManager.addLeaderListener(new ClusterLeaderListener() {
@Override
public void gainLeader() {
startService();
}
@Override
public void loserLeader() {
destoryService();
}
});
}
@Override
public void stop() throws Exception {
destoryService();
shutDown = true;
}
private void startService() {
SchedulerService.startTimer(serverName);
try {
clusterManager.startLeaderLatch();
} catch (Exception e) {
SchedulerService.stopTimer(serverName);
try {
clusterManager.closeLeaderLatch();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
private void destoryService() {
SchedulerService.stopTimer(serverName);
try {
clusterManager.closeLeaderLatch();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class SchedulerService {
static ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
public static void startTimer(final String serverName){
service.scheduleAtFixedRate(()->{
System.out.println("我是服务器"+serverName +",开始已执行任务");
}, 5,1, TimeUnit.SECONDS);
}
public static void stopTimer(final String serverName){
System.out.println("我是服务器:"+serverName+",停止执行任务");
service.shutdown();
}
}
public class App1 {
public static void main(String[] args) {
SchedulerBootstrap sb = new SchedulerBootstrapImpl("服务1");
try {
sb.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class App2 {
public static void main(String[] args) {
SchedulerBootstrap sb = new SchedulerBootstrapImpl("服务2");
try {
sb.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}