zookeeper
- zookeeper选主介绍:
- 在微服务模块引入相关依赖
- 1.在服务层创建SelectMaster,作为选主组件,在类上添加@Component注解
- 2:将SelectMaster中的zookeeper地址连接字符串配置到application.yml配置文件中
- 注入SelectMaster
zookeeper选主介绍:
Zookeeper 会维护一个具有层次关系的数据结构,它非常类似于一个标准的文件系统,集群各节点争抢注册同一路径地址,谁抢到谁就是master
zookeeper基于目录监听机制来选主,多个客户端节点都可以来对zookeeper上某个目录节点进行监听和注册,但只有其中一个能够注册上,谁能注册上谁就是主节点,主节点会保持着和zookeeper目录节点的长连接,只
要该连接不断,那么该客户端节点就一直是主节点,其他客户端节点都会监听者zookeeper的该目录节点,一旦主节点宕机,会立即从其他客户端节点中选出一个新的主节点,也就是说:如果当前master宕机,会立即选出一个
新的master。
在微服务模块引入相关依赖
<!-- zookeeper 客户端 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
1.在服务层创建SelectMaster,作为选主组件,在类上添加@Component注解
2:将SelectMaster中的zookeeper地址连接字符串配置到application.yml配置文件中
yexiang:
preLoad: 1 #预加载时间配置
selectMasterZookeeper: 192.168.200.129:2181
@Data
//对应配置文件中的前缀yexiang
@ConfigurationProperties(prefix = "yexiang")
@Component
public class SelectMaster {
private String selectMasterZookeeper;
//可以放很多节点
Map<String, Boolean> masterMap = new HashMap<String, Boolean>();
/**
* 选主
* @param leaderPath zookeeper目录节点
*/
public void selectMaster (String leaderPath) {
CuratorFramework client = CuratorFrameworkFactory.builder().
connectString(selectMasterZookeeper)
.sessionTimeoutMs(5000) //超时时间
.retryPolicy(new ExponentialBackoffRetry(1000, 3)) //连接不上重试三次
.build();
client.start();
//争抢注册节点
@SuppressWarnings("resource")
LeaderSelector selector = new LeaderSelector(client, leaderPath,
new LeaderSelectorListenerAdapter() {
@Override
public void takeLeadership(CuratorFramework client) throws Exception {
//如果争抢到当前注册节点
masterMap.put(leaderPath, true);
while (true) {
//抢占当前节点
TimeUnit.SECONDS.sleep(3);
}
}
});
masterMap.put(leaderPath, false);
selector.autoRequeue();
selector.start();
}
public boolean checkMaster (String leaderPath) {
Boolean isMaster = masterMap.get(leaderPath);
return isMaster == null ? false : isMaster;
}
}
常量池中添加任意路径,用作微服务在zookeeper上抢注册的地址,谁成功抢到该地址,谁就是主节点,没抢到为从节点,但会继续监视该节点。
public static final String schedule_leaderPath="/chongba/schedule_master";
注入SelectMaster
@Autowired
private SelectMaster selectMaster;
//该注解标注的方法在项目启动时执行
@PostConstruct
public void syncData(){
/**
* 清除缓存原有数据:编写:clearCache()
查询所有任务数据:调用 taskMapper.selectAll()
将任务数据放入缓存:封装Task,调用addTaskToCache(task);
*/
// 选主----
selectMaster.selectMaster(Constants.schedule_leaderPath);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadPoolTaskScheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
//只有主节点才能去进行数据的恢复
boolean master = selectMaster.checkMaster(Constants.schedule_leaderPath);
if(master){
//是主节点
threadLogger.info("schedule-service的主节点进行数据恢复---reloadData");
reloadData();
}else {
//从节点
threadLogger.info("schedule-service的从节点进行备份");
}
}
},TimeUnit.MINUTES.toMillis(systemParams.getPreLoad()));//硬编码
}