3.Spring Boot使用Apache Curator实现leader选举「第四章 ZooKeeper Curator应用场景实战」「架构之路ZooKeeper理论和实战」
Leader选举又称为master选举是zookeeper中最为经典的应用场景了。
一、基本概念
1.1 leader选举的产生
在分布式环境中,相同的业务应用分布在不同的机器上,有些业务逻辑(例如一些耗时的计算,网络I/O处理),往往只需要让整个集群中的某一台机器进行执行,其余机器可以共享这个结果,这样可以大大减少重复劳动,提高性能,于是这Leader选举便是这种场景下的碰到的主要问题。
1.2 ZK的leader机制
ZooKeeper需要在所有的服务(可理解为服务器)中选举出一个Leader,然后让这个Leader来负责管理集群。此时,集群中的其他服务器则成了此Leader的follower。并且,当Leader出现故障的时候,ZooKeeper要能够快速地在Follower中选举出下一个Leader。这就是ZooKeeper的Leader机制
1.3 Curator的两种选举
(1)Leader Latch:参与选举的所有节点,会创建一个顺序节点,其中最小的节点会设置为master节点, 没抢到Leader的节点都监听前一个节点的删除事件,在前一个节点删除后进行重新抢 主,当 master 节点手动调用 close 方法或者 master 节点挂了之后,后续的子节点会抢占master。
(2)Leader Election:Leader Selector和Leader Latch最的差别在于,leader 可以释放领导权以后,还可以继续参与竞争。
1.4 leader election选举过程
leader election选举过程是这样子的:
(1)指派一个进程作为组织者,将任务分发给各节点。 在任务开始前, 哪个节点都不知道谁是leader。
(2)当选举算法开始执行后, 每个节点最终会得到一个唯一的节点作为任务leader。
(3)除此之外, 选举还经常会发生在leader意外宕机的情况下,新的leader要被选举出来。
二、leader election实战
接下来我们看下leader election的这种方式如何进行编码。
2.1 环境说明
(1)基于前面章节《Spring Boot 使用 Curator 操作 ZooKeeper》进行往下编码。
(2)ZooKeeper版本:3.6.2
(3)Curator版本:5.1.0
(4)对于在普通的java项目中,代码是一样的,只要能获取到CuratorFramework就能搞定。
2.2 编写LeaderSelector
编写一个LeaderSelector通过LeaderSelectorListener来监听本节点是否成为leader节点了:
-
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.recipes.leader.LeaderSelector;
- import org.apache.curator.framework.recipes.leader.LeaderSelectorListener;
- import org.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.core.env.Environment;
- import org.springframework.stereotype.Service;
-
- import java.util.Date;
-
- /**
- * leader election
- *
- * @author 悟纤「公众号SpringBoot」
- * @date 2021-04-09
- * @slogan 大道至简 悟在天成
- */
- @Service
- public class LeaderEelectionService {
-
- @Autowired
- private CuratorFramework curatorFramework;
- @Autowired
- private Environment environment;
-
- public void leaderSelector(){
- LeaderSelectorListener listener = new LeaderSelectorListenerAdapter() {
- public void takeLeadership(CuratorFramework client) throws Exception {
- // this callback will get called when you are the leader : 当您成为领导者时,此回调将被调用
-
- // do whatever leader work you need to and only exit this method
- // when you want to relinquish leadership:做您需要做的任何领导工作,并且仅在您要放弃领导时才退出此方法
-
- while (true){
- System.out.println("I'm leader now. port="+environment.getProperty("server.port")+",date:"+new Date());
- Thread.sleep(5000);
- }
- }
- };
-
- LeaderSelector selector = new LeaderSelector(curatorFramework, "/leader", listener);
- //autoRequeue 方法的调用确保此实例在释放领导权后还可能获得领导权。
- selector.autoRequeue(); // not required, but this is behavior that you will probably expect
- selector.start();
- }
-
- }
2.3 在启动类调用选举方法
在启动类调用选举方法,当然这个选举方法可以在任何进行调用,这里只是为了演示而已:
- package com.kfit.springbootcuratordemo;
-
- import com.kfit.springbootcuratordemo.leaderelection.LeaderEelectionService;
- import com.kfit.springbootcuratordemo.register.RegisterService;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.context.ConfigurableApplicationContext;
-
- @SpringBootApplication
- public class SpringbootCuratorDemoApplication {
-
- public static void main(String[] args) {
- ConfigurableApplicationContext ctx = SpringApplication.run(SpringbootCuratorDemoApplication.class, args);
-
- //leader选举
- LeaderEelectionService leaderEelectionService = ctx.getBean(LeaderEelectionService.class);
- leaderEelectionService.leaderSelector();
-
- }
-
-
-
- }
三、leader election源码
从上面我们可以对于leader election使用,简单的很,那么这个具体是怎么一个逻辑呐?如果你也有这样的疑问,请跟随文章进行往下探索。
(1)从方法进入:selector.start();
(2)找到requeue() – internalRequeue()
(3)这里使用线程池的方式进行提交了,核心的代码是doWorkLoop,然后进入到doWork:
购买完整视频,请前往:http://www.mark-to-win.com/TeacherV2.html?id=287