zookeeper-curator-leaderSelector

来源:互联网 发布:大数据需要学哪些技术 编辑:程序博客网 时间:2024/06/11 05:41

constructor

executorService thread pool to use  线程池/默认线程池为守护线程     * @param listener        listener   LeaderSelectorListener 监听器     */    public LeaderSelector(CuratorFramework client, String leaderPath, CloseableExecutorService executorService, LeaderSelectorListener listener)    {        //省略参数校验        this.client = client;        this.listener = new WrappedListener(this, listener);        hasLeadership = false;        this.executorService = executorService;        mutex = new InterProcessMutex(client, leaderPath)  //zookeeper 维护的锁        {            @Override            protected byte[] getLockNodeBytes()            {                return (id.length() > 0) ? getIdBytes(id) : null;            }        };    }

start

 /**     * Attempt leadership. This attempt is done in the background - i.e. this method returns     * immediately.<br><br>     * <b>IMPORTANT: </b> previous versions allowed this method to be called multiple times. This     * is no longer supported. Use {@link #requeue()} for this purpose.     */    public void start()    {        //省略参数校验         client.getConnectionStateListenable().addListener(listener);  //监听连接状态改变        requeue();   //重新排队    }

internalRequeue

  //同一个leaderSelect保证只有一个竞争 private synchronized boolean internalRequeue()    {        if ( !isQueued && (state.get() == State.STARTED) )         {            isQueued = true;                //future返回空参,异步            Future<Void> task = executorService.submit(new Callable<Void>()            {                @Override                public Void call() throws Exception                {                    try                    {                        doWorkLoop();   //真正的获取leader                    }                    finally                    {                        clearIsQueued();                        //开启自动重新排队,会一直竞争leader                        if ( autoRequeue.get() )                          {                            internalRequeue();                        }                    }                    return null;                }            });            ourTask.set(task);            return true;        }        return false;    }

doWork

    @VisibleForTesting    void doWork() throws Exception    {        hasLeadership = false;        try        {            //尝试获取锁            mutex.acquire();              //在整个acquire 到release 为leader状态            hasLeadership = true;              try            {                if ( debugLeadershipLatch != null )                {                    debugLeadershipLatch.countDown();                }                if ( debugLeadershipWaitLatch != null )                {                    debugLeadershipWaitLatch.await();                }                //保证同一个path下的任意leaderSeclector,只有一个listen执行此业务代码                listener.takeLeadership(client);               }            catch ( InterruptedException e )            {                Thread.currentThread().interrupt();                throw e;            }            catch ( Throwable e )            {                ThreadUtils.checkInterrupted(e);            }            finally            {                clearIsQueued();            }        }        catch ( InterruptedException e )        {            Thread.currentThread().interrupt();            throw e;        }        finally        {            if ( hasLeadership )            {                hasLeadership = false;                try                {                    mutex.release();  //释放锁                }                catch ( Exception e )                {                    ThreadUtils.checkInterrupted(e);                    log.error("The leader threw an exception", e);                    // ignore errors - this is just a safety                }            }        }    }