上一篇我们讲解如何使用Curator来完成分布式锁的相关操作,这一节中我们使用Curator来实现群首选举。
Curator中有两种类都可以实现群首选举,一个是 LeaderLatch, 一个是 LeaderSelector 。第一种会告诉你是否成为leader,当你close的时候才会交出leader权限,第二种可以在你成为leader之后,更方便的决定是否要交出leader权限,相比之下更加灵活。
接下来我们主要讲解 LeaderLatch 的使用。
一、实例化:
public LeaderLatch(CuratorFramework client,
String latchPath)
此为实例化 LeaderLatch ,latchPath即为要群首选举的路径。
二、添加监听:
public void addListener(LeaderLatchListener listener)
此为添加监听,里面的有 isLeader() 方法回调与 notLeader() 方法,当成为leader的时候,会调用 isLeader() 方法,当连接zooKeeper的状态为 SUSPENDED or LOST 的时候,会调用 notLeader() 方法,即此时与ZooKeeper连接不上了, 不应该再执行leader相关操作
三、开始监听:
leaderLatch.start();
四、关闭监听/交出leader权限:
leaderLatch.close();
五、示例:
package com.happyheng.leader;
import com.happyheng.consts.ZooKeeperConsts;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.leader.LeaderLatch;
import org.apache.curator.framework.recipes.leader.LeaderLatchListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
/**
*
* Created by happyheng
*/
@Service
public class DistributeSelectorLatch {
private static final Logger logger = LoggerFactory.getLogger(DistributeSelectorLatch.class);
@Autowired
private CuratorFramework curatorFramework;
private LeaderLatch leaderLatch = null;
@PostConstruct
public void selectLeader() {
leaderLatch = new LeaderLatch(curatorFramework, "/leader");
leaderLatch.addListener(new LeaderLatchListener() {
@Override
public void isLeader() {
logger.info("成为leader ");
ZooKeeperConsts.isMaster = true;
}
@Override
public void notLeader() {
/**
* 注意当连接zooKeeper的状态为 SUSPENDED or LOST 的时候,会调用此方法
*/
logger.info("失去leader ");
ZooKeeperConsts.isMaster = false;
}
});
try {
leaderLatch.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@PreDestroy
public void destroy() {
if (leaderLatch == null) {
return;
}
try {
leaderLatch.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}