集群下选举Leader干活
/**
* @author tangzq
* @date 2020/7/11 23:46
*/
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.leader.LeaderSelector;
import org.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.utils.CloseableUtils;
import java.util.ArrayList;
import java.util.List;
public class LeaderSelectorTest {
private static final String PATH = "/zoo/leader";
public static void main(String[] args) {
List<LeaderSelector> selectors = new ArrayList<>();
List<CuratorFramework> clients = new ArrayList<>();
try {
for (int i = 0; i < 10; i++) {
CuratorFramework client = getClient();
clients.add(client);
final String name = "client#" + i;
LeaderSelector leaderSelector = new LeaderSelector(client, PATH, new LeaderSelectorListenerAdapter() {
@Override
public void takeLeadership(CuratorFramework client) throws Exception {
while (true) {
System.out.println(name + ":I am leader.");
Thread.sleep(2000);
}
}
@Override
public void stateChanged(CuratorFramework client, ConnectionState newState) {
}
});
leaderSelector.autoRequeue();
leaderSelector.start();
selectors.add(leaderSelector);
}
Thread.sleep(Integer.MAX_VALUE);
} catch (Exception e) {
e.printStackTrace();
} finally {
for (CuratorFramework client : clients) {
CloseableUtils.closeQuietly(client);
}
for (LeaderSelector selector : selectors) {
CloseableUtils.closeQuietly(selector);
}
}
}
private static CuratorFramework getClient() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("ilove:2181,ilove:2182,ilove:2183")
.retryPolicy(retryPolicy)
.sessionTimeoutMs(6000)
.connectionTimeoutMs(3000)
.namespace("tzq")
.build();
client.start();
return client;
}
}
LeaderSelector 同一Path下,只会有一个client成为leader干活,如果这个leader宕机了,其他节点会选举出新的leader继续干活。
监听节点变化
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
/**
* @author tangzq
* @date 2020/7/12 14:34
*/
public class Listener {
private final static ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
public static void main(String[] args) {
NodeCache nodeCache;
NodeCacheListener listener = new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
try {
System.out.println("listener working.");
} catch (RuntimeException ex) {
}
}
};
CuratorFramework zk = getClient();
nodeCache = new NodeCache(zk, "/tzq/listener");
nodeCache.getListenable().addListener(listener, executor);
try {
nodeCache.start();
Thread.sleep(Integer.MAX_VALUE);
} catch (Exception e) {
e.printStackTrace();
}
}
public static CuratorFramework getClient() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("ilove:2181,ilove:2182,ilove:2183")
.retryPolicy(retryPolicy)
.sessionTimeoutMs(6000)
.connectionTimeoutMs(3000)
.namespace("tzq")
.build();
client.start();
return client;
}
}
实现分布式锁
Curator Framework 四种重连策略
Curator 四种重连策略
1.RetryUntilElapsed(int maxElapsedTimeMs, int sleepMsBetweenRetries)
以sleepMsBetweenRetries的间隔重连,直到超过maxElapsedTimeMs的时间设置
2.RetryNTimes(int n, int sleepMsBetweenRetries)
指定重连次数
3.RetryOneTime(int sleepMsBetweenRetry)
重连一次,简单粗暴
4.ExponentialBackoffRetry
ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries)
ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs)
时间间隔 = baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)))