概述
使用zookeeper自己来实现选举还是有点麻烦的(使用zookeeper实现选举),这个时候可以使用curator
正如官网所说,curator对于zookeeper就像guava对于java,它让我们能更加便利、可靠地使用zookeeper。
这篇博客会介绍如何通过curator来实现选举。
使用方式
引入jar
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.11.0</version>
</dependency>
使用LeaderSelector实现选举
String zookeeperAddr = "127.0.0.1:2181";
//zk的重连策略
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
//获取连接
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperAddr, retryPolicy);
client.start();
String path = "/newserver/leader"; //选举的节点信息放在这个path下
//这里建议使用LeaderSelectorListenerAdapter,它实现了stateChanged,当与zk失连后,会自动取消领导权
LeaderSelector leaderSelector = new LeaderSelector(client, path, new LeaderSelectorListenerAdapter() {
@Override
public void takeLeadership(CuratorFramework client) throws Exception {
System.out.println("成为leader了");
Thread.sleep(10000); //sleep 10秒
//注意当takeLeadership方法返回之后,相当于放弃成为leader了
System.out.println("放弃成为leader");
}
});
//放弃领导权之后,自动再次竞选
leaderSelector.autoRequeue();
leaderSelector.start();
TimeUnit.HOURS.sleep(1);
测试结果
两个竞选者轮流成为leader
使用LeaderLatch来实现选举
String zookeeperAddr = "127.0.0.1:2181";
//重连策略
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
//获取连接
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperAddr, retryPolicy);
client.start();
String path = "/newserver/leader";
LeaderLatch leaderLatch = new LeaderLatch(client, path);
leaderLatch.start();
leaderLatch.await();//阻塞等待自己有领导权
System.out.println("成为leader了");
new BufferedReader(new InputStreamReader(System.in)).readLine();//输入参数后,放弃领导权
leaderLatch.close();
System.out.println("放弃成为leader,当前是否有领导权:" + leaderLatch.hasLeadership());
LeaderLatch与LeaderSelector的不同
1)LeaderSelector使用回调的方式来处理获取领导权之后的操作,LeaderLatch提供了类似于CountDownLatch的方式,可以阻塞程序,直到服务获取领导权为止。
https://stackoverflow.com/questions/17998616/leaderlatch-vs-leaderselector