[zk] CuratorFramework的LeaderLatch选主解析
三个要点:分布式锁、顺序选主、监听方式
主要竞选流程
1、参与竞选的LeaderLatch实例在zookeeper上的{latchpath}目录创建临时有序子节点,如{latchpath}/latch-{seq},值默认为"".getBytes()。
2、创建有序节点成功后,回调函数,读取节点{latchpath}目录的所有子节点信息,对子节点的名称按{seq}从小到大排序,判断如果当前创建节点的值为最小的节点值,则断定当前的节点为master节点,回调执行isLeader的listener。否则当前节点未竞选master成功,成为一个follower,注册对前一个{seq}节点watcher事件,在watcher到NO_NODE事件后尝试重新竞选master。
1、LeaderLatch#start 启动竞选
public void start() throws Exception
{
//检测当前的LeaderLatch实例的状态为未开始选举
Preconditions.checkState(state.compareAndSet(State.LATENT, State.STARTED), "Cannot be started more than once");
//startTask为Feature对象,记录返回信息,AfterConnectionEstablished创建一个单线程池,提交任务(待zk的client连接建立后执行如下的 runnable 代码)
startTask.set(AfterConnectionEstablished.execute(client, new Runnable()
{
@Override
public void run()
{
try
{
//执行具体的选举逻辑
internalStart();
}
finally
{
startTask.set(null);
}
}
}));
}
2、LeaderLatch#internalStart
private synchronized void internalStart()
{
//二次确认当前转态是否为started
if ( state.get() == State.STARTED )
{
//此时连接已经建立,这里添加一个zk的连接状态监听器,用于执行连接重连(重新参与竞选,reset)、阻塞(重置leader为false)、丢失(重置leader为false)等事件的逻辑
client.getConnectionStateListenable().addListener(listener);
try
{
//竞选相关的复用核心逻辑
reset();
}
catch ( Exception e )