Curator实现Master/Leader选举

在实际生产中,特别是分布式系统中,我们经常遇到这样的场景:一个复杂的任务,近需要从分布式机器中选出一台机器来执行。诸如此类的问题,我们统称为“Master选举”。比如,在分布式系统中很常见的一个问题就是定时任务的执行。如果多台机器同时执行相同的定时任务,业务复杂则可能出现灾难性的后果。本篇博客就以定时任务为例来示例说明Curator的Master选举用法。

原理
利用zookeeper来实现Master选举的基本思路如下: 
选择一个根节点(与其他业务隔离),比如/jobMaster,多台机器同时在此节点下面创建一个子节点/jobMaster/lock,zookeeper保证了最终只有一台机器能够创建成功,那么这台机器将成为Master。由它来执行业务操作。

Curator所做的事情就是将上面的思路进行了封装,把原生API的节点创建、事件监听和自动选举进行整合封装,提供了一套简单易用的解决方案。

添加Maven依赖
 

   <dependencies>
       ...
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.12.0</version>
        </dependency>
        ...
    </dependencies>

Curator提供了两种选举方案:Leader Latch和Leader Election。这里主要介绍下Leader Latch方案,Leader Latch 随机从候选着中选出一台作为leader,选中之后除非调用close()释放leadship,否则其他的后选择无法成为leader。

测试代码如下:

public class LeaderLatchTest {

    private static final String PATH = "/demo/leader";


    public static void main(String[] args) throws UnknownHostException {

       LeaderLatch leaderLatch = null;
       CuratorFramework client = null;

        final String id = "client#" + InetAddress.getLocalHost().getHostAddress();

        try {

            client = getClient();

            final LeaderLatch finalLeaderLatch = new LeaderLatch(client, PATH, id);
            leaderLatch = finalLeaderLatch;

            finalLeaderLatch.addListener(new LeaderLatchListener() {

                @Override
                public void isLeader() {
                    System.out.println(finalLeaderLatch.getId() + ":I am leader.");
                }

                @Override
                public void notLeader() {
                    System.out.println(finalLeaderLatch.getId() + ":I am not leader.");
                }
            });

            finalLeaderLatch.start();

            Thread.sleep(Integer.MAX_VALUE);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
                CloseableUtils.closeQuietly(client);
                CloseableUtils.closeQuietly(leaderLatch);
        }
    }

    private static CuratorFramework getClient() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("192.168.110.201:2181,192.168.110.202:2181,192.168.110.203:2181")  //zookeeper集群地址
                .retryPolicy(retryPolicy)
                .sessionTimeoutMs(6000)
                .connectionTimeoutMs(3000)
                .namespace("demo")
                .build();
        client.start();
        return client;
    }
}

机器A运行结果如下:

A机器先运行,被选主为leader。B机器后启动,没有收到消息,没有输出。

关闭服务器A的网络,A降级为从机

3秒后服务器B升级为主机

如果3内服务器A恢复网络,服务器A依然是leader。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值