【问题标题】:Curator - How to know current node is leader or notCurator - 如何知道当前节点是否是领导者
【发布时间】:2017-07-11 15:24:04
【问题描述】:

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

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

Zookeeper 框架将负责选举节点。我需要知道选定的 Curator 客户端是否指向领导者。

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

用例如下。用例中涉及微服务。

如果LEADER对应的微服务宕机了,那么需要再选择一个leader。每个微服务都可以被视为一个 Z-NODE。如果删除 Z-NODE,则会触发并监听 NODEREMOVED 事件。

LEADER 不应该是微服务宕机节点。

【问题讨论】:

  • 我认为大部分已经在基础 zookeper 算法中实现。任何节点都可以监视其他 z-node,并且一旦领导者宕机,该 z-node 的观察者将成为领导者。我不清楚什么“领导者不应该是微服务宕机节点”,如果一个节点宕机,如果系统有法定人数,领导者将被选举。

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


【解决方案1】:

我认为第三个实例启动时,LeaderLatch(first, second) 的状态发生了变化。

leaderLatch.hasLeadership()

应在足够的实例(第 3 个)启动后执行。

或在发生这种情况时注册callback method

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

【讨论】:

    【解决方案2】:

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

    你应该先等待leader选举完成。

    不幸的是,我无法找到使用 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. 使用进程间通信从框架中查询当前节点
    2. 使用配置的排序器对节点进行排序
    3. 为了查询的目的,将排序后的第一个节点标记为领导节点

    还有一个有点等价的查询:

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

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

    【讨论】:

    • docs 中的 await () 方法。除非线程被中断或关闭,否则当前线程一直等待直到此实例获得领导权。据此,我将无法知道所选节点是否为领导者。实际上这 3 个实例是在集群中配置的。已编辑的问题。
    • @RamaKrishna.G,同意,我将删除此答案并对其进行更多研究。
    • 真的很适合去花钱,让我知道答案。谢谢@Prokhorov
    • @RamaKrishna.G,好吧,据我所知,我的答案的第一部分成立,但我无法找到任何方法来实际判断事件是否被触发领导选举完成。 The notifications only fire when leadership changes, so as far as that framework can tell, a non-leader election participant that wasn't elected will not be able to log it.
    • @Prokhorov,感谢 cmets。我有一个基本的疑问。当在集群中设置节点时,领导者选举会自动发生。 LeaderLatch 会做什么?使用它,我可以编写我的领导选举算法吗?还是在框架选举出领导者时获取通知?
    【解决方案3】:

    我相信您需要通过以下代码将侦听器添加到 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")
          }
        })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多