Java – how to effectively use the leaderelection recipe for curators using zookeeper?

I am using the Apache cursor library to conduct leadership elections on zookeeper My application code is deployed in various machines. I need to execute my code from one machine. That's why I conduct a leadership election on zookeeper so that I can check whether I am a leader and then execute this code

Here is my leaderelectionexecution class, which ensures that every application has a curator instance

public class LeaderElectionExecutor {

    private ZookeeperClient zookClient;

    private static final String LEADER_NODE = "/testleader";

    private static class Holder {
        static final LeaderElectionExecutor INSTANCE = new LeaderElectionExecutor();
    }

    public static LeaderElectionExecutor getInstance() {
        return Holder.INSTANCE;
    }

    private LeaderElectionExecutor() {
        try {
            String hostname = Utils.getHostName();

            String nodes = "host1:2181,host2:2181;

            zookClient = new ZookeeperClient(nodes,LEADER_NODE,hostname);
            zookClient.start();

            // added sleep specifically for the leader to get selected
            // since I cannot call isLeader method immediately after starting the latch
            TimeUnit.MINUTES.sleep(1);
        } catch (Exception ex) {
            // logging error
            System.exit(1);
        }
    }

    public ZookeeperClient getZookClient() {
        return zookClient;
    }
}

Here is my zookeeperclient code –

// can this class be improved in any ways?
public class ZookeeperClient {

    private CuratorFramework client;
    private String latchPath;
    private String id;
    private LeaderLatch leaderLatch;

    public ZookeeperClient(String connString,String latchPath,String id) {
        client = CuratorFrameworkFactory.newClient(connString,new ExponentialBackoffRetry(1000,Integer.MAX_VALUE));
        this.id = id;
        this.latchPath = latchPath;
    }

    public void start() throws Exception {
        client.start();
        leaderLatch = new LeaderLatch(client,latchPath,id);
        leaderLatch.start();
    }

    public boolean isLeader() {
        return leaderLatch.hasLeadership();
    }

    public Participant currentLeader() throws Exception {
        return leaderLatch.getLeader();
    }

    public void close() throws IOException {
        leaderLatch.close();
        client.close();
    }

    public CuratorFramework getClient() {
        return client;
    }

    public String getLatchPath() {
        return latchPath;
    }

    public String getId() {
        return id;
    }

    public LeaderLatch getLeaderLatch() {
        return leaderLatch;
    }
}

Now in my application, I'm using this code –

public void method01() {
    ZookeeperClient zookClient = LeaderElectionExecutor.getInstance().getZookClient();
    if (zookClient.isLeader()) {
        // do something
    }
}

public void method02() {
    ZookeeperClient zookClient = LeaderElectionExecutor.getInstance().getZookClient();
    if (zookClient.isLeader()) {
        // do something
    }
}

Problem statement:-

In the curator library – calling isleader () has no effect immediately after starting the lock Leadership selection takes time And for this reason, I've added a minute of sleep to my leaderelectionexecution code, but I don't think it's the right way

Is there a better way? With this in mind, I need a way to check if I'm a leader, and then execute this code I can't do everything in one method, so I need to call isleader methods from different classes and methods to check whether I'm the leader, and then execute this code

I'm using zookeeper 3.4 5 and cursor 1.7 1 version

Solution

Once I solve a problem very similar to yours This is how I did it

First, I have my objects managed by spring So I have a leaderlatch that can be injected through the container One of the components using leaderlatch is leadershipwatcher, an implementation of the runnable interface that sends leadership events to other components These last components are the implementation of the interface I named leadershipobserver The implementation of leadershipwatcher mainly includes the following code:

@Component
public class LeadershipWatcher implements Runnable {
  private final LeaderLatch leaderLatch;
  private final Collection<LeadershipObserver> leadershipObservers;

  /* constructor with @Inject */

  @Override
  public void run() {
    try {
      leaderLatch.await();

      for (LeadershipObserver observer : leadershipObservers) {
        observer.granted();
      }
    } catch (InterruptedException e) {
      for (LeadershipObserver observer : leadershipObservers) {
        observer.interrupted();
      }
    }
  }
}

Since this is just a sketch, I suggest you strengthen this code, maybe apply command mode to call observers, or even submit observers to the thread pool if their jobs are blocked or run CPU intensive tasks for a long time

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>