Curator之Leader选举

本文介绍使用Zookeeper实现Leader选举的两种方式:基于LeaderSelector的异步非阻塞选举及基于LeaderLatch的阻塞等待机制。前者适用于需要灵活控制Leadership且支持重新竞争的情况,后者则适用于只需一次性获得Leadership的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于LeaderSelector实现

  当客户端成为Leader时,采用异步回调的方式调用takeLeadership,执行相应的逻辑;
  优点如下:
    1. 异步非阻塞;
    2. 对于Leadership控制很灵活;
    3. Leadership释放后可以重新排队竞争Leader;
    4. 连接出现异常时,原先Leader正在执行的逻辑会被取消,防止出现并发;

/**
 * 类说明:Leader选举客户端
 * 
 * @author ruipeng.lrp
 * @since 2017/10/19
 **/
public class LeaderSelectorClient implements Closeable{
    private static final String NAMESPACE = "dps";
    private static final String LOCK_PATH = "/leader";
    private CuratorFramework client;
    private LeaderSelector leaderSelector;
    private String connectString = "30.117.84.40:2181";
    private int sessionTimeoutMs = 15*1000;
    private int connectionTimeoutMs = 3*1000;
    private String name;

    public void init() throws Exception{
        try{
            client = CuratorFrameworkFactory.builder()
                    .connectString(this.connectString)
                    .sessionTimeoutMs(sessionTimeoutMs)
                    .connectionTimeoutMs(connectionTimeoutMs)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3)) //断连重试策略
                    .namespace(NAMESPACE) //应用隔离,相当于chroot
                    .build();
            leaderSelector = new LeaderSelector(client, LOCK_PATH, Executors.newSingleThreadExecutor(), new LeaderSelectorListenerAdapter(){

                @Override
                public void takeLeadership(CuratorFramework client) throws Exception {
                    leaderAction();
                }

            });
            leaderSelector.autoRequeue();
            client.start();
            leaderSelector.start();
        }catch(Exception e){
            CloseableUtils.closeQuietly(leaderSelector);
            CloseableUtils.closeQuietly(client);
        }
    }

    //成为leader后的业务逻辑
    public void leaderAction() throws Exception{
        while(true){
            System.out.println(name + " is the leader");
            Thread.sleep(1000);
        }
    }

    @Override
    public void close() throws IOException {
        CloseableUtils.closeQuietly(leaderSelector);
        CloseableUtils.closeQuietly(client);
        System.out.println("shutting down...");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static void main(String[] args) throws Exception {
        LeaderSelectorClient c1 = new LeaderSelectorClient();
        c1.init();
        c1.setName("A1");
    }
}

基于LeaderLatch实现

  相当于分布式的CountDownLatch,阻塞等待直到成为leader,leadership释放后无法再次排队竞争leader;

public class LeaderLatchClient implements Closeable{
    private static final String NAMESPACE = "dps";
    private static final String LOCK_PATH = "/leader";
    private CuratorFramework client;
    private LeaderLatch leaderLatch;
    private String connectString = "30.117.84.40:2181";
    private int sessionTimeoutMs = 15*1000;
    private int connectionTimeoutMs = 3*1000;
    private String name;

    public void init() throws Exception{
        try{
            client = CuratorFrameworkFactory.builder()
                    .connectString(this.connectString)
                    .sessionTimeoutMs(sessionTimeoutMs)
                    .connectionTimeoutMs(connectionTimeoutMs)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3)) //断连重试策略
                    .namespace(NAMESPACE) //应用隔离相当于chroot
                    .build();
            leaderLatch = new LeaderLatch(client, LOCK_PATH);
            client.start();
            leaderLatch.start();
        }catch(Exception e){
            CloseableUtils.closeQuietly(leaderLatch);
            CloseableUtils.closeQuietly(client);
        }
    }

    //成为leader后的业务逻辑
    public void leaderAction() throws Exception{
        leaderLatch.await(); //阻塞等待成为leader
        //持续关注leadership状态变更
        while(leaderLatch.hasLeadership()){
            System.out.println(name + " is the leader");
            Thread.sleep(1000);
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void close() throws IOException {
        CloseableUtils.closeQuietly(leaderLatch);
        CloseableUtils.closeQuietly(client);
    }

    public static void main(String[] args) throws Exception {
        LeaderLatchClient c1 = new LeaderLatchClient();
        c1.init();
        c1.setName("A1");
        c1.leaderAction();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值