策展人 - 如何知道当前节点是不是领导者

时间:2017-07-11 15:24:05

标签: java load-balancing apache-zookeeper apache-curator

只是想知道是否有任何API知道特定节点是使用Curator框架中的CuratorFramework类的领导者。我正在使用LeaderLatch,但即使Node是领导者也不工作(由Zookeeper框架选举)。

注意:在群集设置中配置3个节点。

Zookeeper框架将负责选择一个节点。我需要知道选定的策展人客户端是否指向领导者。

String zkConnString = "172.18.54.211:2181";

RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client1 = CuratorFrameworkFactory.newClient(zkConnString, retryPolicy);
client1.start();

 LeaderLatch leaderLatch = new LeaderLatch(client1, "/FirstNode");
 try {
    leaderLatch.start();

} catch (Exception e1) {
    e1.printStackTrace();
}

System.out.println("has leader ship ? "+leaderLatch.hasLeadership());

输出

has leader ship ? false

用例如下。微服务涉及用例。 enter image description here

如果LEADER相应的Micro Service出现故障,则需要选择其他领导者。每个Micro服务都可以视为Z-NODE。如果删除Z-NODE,将触发并监听NODEREMOVED事件。

LEADER不应该是Micro Service down节点。

3 个答案:

答案 0 :(得分:2)

我认为当第三个实例开始时,LeaderLatch(第一个,第二个)的状态已经改变。

leaderLatch.hasLeadership()
应在足够的实例(第3次)开始后执行

发生这种情况时,

或注册表callback method

实现接口LeaderLatchListener并覆盖isLeader()notLeader()是一个好主意。

答案 1 :(得分:0)

根据documentation,领导人选举是异常的。这意味着在您开始领导选举之后,领导者信息不一定立即可用。

你应该等待领导人选举先完成。

不幸的是,我无法使用org/apache/curator/framework/recipes/leader包中的类找到获取有关选举完成信息的简洁方法:API仅提供检查领导更改的方法。

我能找到的最接近的查询是这个(使用Java8):

new LeaderSelector(clientFramework, path, new NoOpLeaderSelectorListener())
    .getParticipants().stream()
    .filter(Participant::isLeader)
    .map(Participant::getId)
    .findAny()
    .ifPresent(<... do something with leader node Id ...>);

但我仍然不清楚这是否会产生比原始变体更确定的正确结果。

它将做的是:

  1. 使用进程间通信从Framework查询当前节点
  2. 使用已配置的分拣机
  3. 对节点进行排序
  4. 为了查询的目的,在排序为Leader节点之后将第一个节点标记为
  5. 还有一个有点等同的查询:

    new LeaderSelector(clientFramework, path, new NoOpLeaderSelectorListener())
      .getLeader()
    

    第一个和第二个之间的区别在于,如果没有节点,则返回虚拟参与者是对象,而如果没有节点,则第一个查询相对透明地返回Optional.empty()

答案 2 :(得分:0)

我相信你需要通过以下代码为LeadLatch添加监听器:

    leaderLatch.addListener(new LeaderLatchListener {
      override def isLeader(): Unit = {
        println(s"I am the lead $i")
      }

      override def notLeader(): Unit = {
        println(s"i am not the leader any more $i")
      }
    })