依星源码资源网,依星资源网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

【好消息,好消息,好消息】VIP会员可以发表文章赚积分啦 !
查看: 98|回复: 0

基于Zookeeper实现调度任务选主及心跳检测

[复制链接] 主动推送

1万

主题

1万

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
15435
发表于 2025-4-15 11:53:12 | 显示全部楼层 |阅读模式
基于Zookeeper实现调度任务选主及心跳检测
在微服务架构中使用ZooKeeper实现分布式任务调度选主,并确保Follower节点能实时监控Master状态并及时触发重新选举,可以通过以下方案实现:

一、核心设计原理1. ZooKeeper特性利用ZK功能在选主中的应用
临时节点(EPHEMERAL)Master创建临时节点,会话断开时节点自动删除(相当于心跳检测)
Watcher机制Follower监听Master节点变化
顺序节点(SEQUENTIAL)实现公平的选举排序
2. 状态监控流程

基于Zookeeper实现调度任务选主及心跳检测

基于Zookeeper实现调度任务选主及心跳检测

二、完整实现方案1. 添加依赖
  1. <!-- Curator客户端(推荐) -->
  2. <dependency>
  3.     <groupId>org.apache.curator</groupId>
  4.     <artifactId>curator-recipes</artifactId>
  5.     <version>5.5.0</version>
  6. </dependency>
复制代码
2. 选主服务实现
  1. import org.apache.curator.framework.CuratorFramework;
  2. import org.apache.curator.framework.recipes.leader.LeaderSelector;
  3. import org.apache.curator.framework.recipes.leader.LeaderSelectorListener;
  4. import org.apache.curator.framework.state.ConnectionState;
  5. import org.springframework.stereotype.Component;

  6. import javax.annotation.PostConstruct;
  7. import javax.annotation.PreDestroy;

  8. @Component
  9. public class ZkLeaderElection {

  10.     private final CuratorFramework zkClient;
  11.     private LeaderSelector leaderSelector;
  12.     private volatile boolean isLeader = false;

  13.     public ZkLeaderElection(CuratorFramework zkClient) {
  14.         this.zkClient = zkClient;
  15.     }

  16.     @PostConstruct
  17.     public void init() throws Exception {
  18.         leaderSelector = new LeaderSelector(zkClient, "/scheduler/leader",
  19.             new LeaderSelectorListener() {
  20.                 @Override
  21.                 public void takeLeadership(CuratorFramework client) throws Exception {
  22.                     // 成为Leader后的逻辑
  23.                     isLeader = true;
  24.                     System.out.println("当前节点当选为Leader");
  25.                     try {
  26.                         while (true) {
  27.                             Thread.sleep(1000); // 模拟持续工作
  28.                         }
  29.                     } finally {
  30.                         isLeader = false;
  31.                     }
  32.                 }

  33.                 @Override
  34.                 public void stateChanged(CuratorFramework client, ConnectionState newState) {
  35.                     // 连接状态变化处理
  36.                     if (newState == ConnectionState.LOST) {
  37.                         isLeader = false;
  38.                     }
  39.                 }
  40.             });

  41.         leaderSelector.autoRequeue(); // 自动重新参与选举
  42.         leaderSelector.start();
  43.     }

  44.     @PreDestroy
  45.     public void shutdown() {
  46.         if (leaderSelector != null) {
  47.             leaderSelector.close();
  48.         }
  49.     }

  50.     public boolean isLeader() {
  51.         return isLeader;
  52.     }
  53. }
复制代码
3. 增强型状态监控(生产级)
  1. // 在init()方法中添加以下逻辑
  2. public void init() throws Exception {
  3.     // ...原有代码...
  4.    
  5.     // 添加额外的心跳检测
  6.     zkClient.getConnectionStateListenable().addListener((client, newState) -> {
  7.         if (newState == ConnectionState.RECONNECTED) {
  8.             // 重连后强制检查Leader状态
  9.             checkLeaderStatus();
  10.         }
  11.     });
  12.    
  13.     // 启动定时检查任务
  14.     Executors.newSingleThreadScheduledExecutor()
  15.         .scheduleAtFixedRate(this::checkLeaderStatus, 0, 5, TimeUnit.SECONDS);
  16. }

  17. private void checkLeaderStatus() {
  18.     try {
  19.         if (zkClient.checkExists().forPath("/scheduler/leader") == null) {
  20.             System.out.println("Leader节点不存在,触发重新选举");
  21.         }
  22.     } catch (Exception e) {
  23.         e.printStackTrace();
  24.     }
  25. }
复制代码
三、关键优化点1. 双Watch机制
  1. // 除了LeaderSelector内置监听,额外添加数据Watch
  2. zkClient.getData().usingWatcher((Watcher) event -> {
  3.     if (event.getType() == Watcher.Event.EventType.NodeDeleted) {
  4.         System.out.println("Leader节点被删除,立即触发选举");
  5.     }
  6. }).forPath("/scheduler/leader");
复制代码
2. 选举性能优化参数推荐值说明
sessionTimeoutMs10000-15000ms根据网络状况调整
leaderSelector.autoRequeue()必须启用保证节点退出后重新参与选举
retryPolicy.baseSleepTimeMs1000ms首次重试延迟

3. 故障转移时间控制
  1. // 在ZK配置中优化
  2. @Bean
  3. public CuratorFramework zkClient() {
  4.     return CuratorFrameworkFactory.builder()
  5.         .connectString("zk1:2181,zk2:2181,zk3:2181")
  6.         .sessionTimeoutMs(15000) // 会话超时
  7.         .connectionTimeoutMs(5000) // 连接超时
  8.         .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // 重试策略
  9.         .build();
  10. }
复制代码
故障转移时间 = 会话超时时间 + 选举时间(通常可控制在15秒内)

四、生产环境建议1. 监控指标指标名称采集方式告警阈值
ZK选举次数ZK的leader_election计数器1小时内>5次
Master存活时间节点数据中的时间戳连续3次<30秒
节点连接状态Curator事件监听RECONNECTED状态持续>1分钟

2. 部署架构
  1. [微服务实例1] [微服务实例2] [微服务实例3]
  2.       |            |            |
  3.       +------------+------------+
  4.                    |
  5.            [ZooKeeper Ensemble]
  6.                    |
  7.             [监控系统(Prometheus + Grafana)]
复制代码
3. 异常场景处理
  • 脑裂防护:启用ZK的quorum机制(至少3节点)
  • 网络分区:配合Sidecar代理检测真实网络状态
  • 持久化问题:定期备份/scheduler节点数据

五、与Spring Cloud集成1. 健康检查端点
  1. @RestController
  2. @RequestMapping("/leader")
  3. public class LeaderController {
  4.    
  5.     @Autowired
  6.     private ZkLeaderElection election;

  7.     @GetMapping("/status")
  8.     public ResponseEntity<String> status() {
  9.         return election.isLeader()
  10.             ? ResponseEntity.ok("MASTER")
  11.             : ResponseEntity.ok("FOLLOWER");
  12.     }
  13. }
复制代码
2. 调度任务示例
  1. @Scheduled(fixedRate = 5000)
  2. public void scheduledTask() {
  3.     if (zkLeaderElection.isLeader()) {
  4.         System.out.println("只有Master执行的任务...");
  5.     }
  6. }
复制代码
六、对比Redisson方案维度ZooKeeper方案Redisson方案
实时性秒级(依赖ZK会话超时)秒级(依赖Redis TTL)
可靠性高(CP系统)中(依赖Redis持久化)
运维复杂度较高(需维护ZK集群)较低(复用Redis)
适用场景强一致性要求的系统允许短暂脑裂的场景


通过以上方案,你的微服务可以实现:
  • 秒级故障检测:基于ZK临时节点和Watcher机制
  • 自动快速选主:利用Curator的选举算法
  • 生产级可靠性:多重监控和防护机制
  • 无缝集成Spring生态:与@Scheduled等组件协同工作






相关帖子

扫码关注微信公众号,及时获取最新资源信息!下载附件优惠VIP会员6折;永久VIP4折
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

免责声明:
1、本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
2、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,请勿任何商业目的与商业用途。
3、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
4、论坛的所有内容都不保证其准确性,完整性,有效性,由于源码具有复制性,一经售出,概不退换。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
5、用户使用本网站必须遵守适用的法律法规,对于用户违法使用本站非法运营而引起的一切责任,由用户自行承担
6、本站所有资源来自互联网转载,版权归原著所有,用户访问和使用本站的条件是必须接受本站“免责声明”,如果不遵守,请勿访问或使用本网站
7、本站使用者因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负责,本站不承担任何责任。
8、凡以任何方式登陆本网站或直接、间接使用本网站资料者,视为自愿接受本网站声明的约束。
9、本站以《2013 中华人民共和国计算机软件保护条例》第二章 “软件著作权” 第十七条为原则:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。若有学员需要商用本站资源,请务必联系版权方购买正版授权!
10、本网站如无意中侵犯了某个企业或个人的知识产权,请来信【站长信箱312337667@qq.com】告之,本站将立即删除。
郑重声明:
本站所有资源仅供用户本地电脑学习源代码的内含设计思想和原理,禁止任何其他用途!
本站所有资源、教程来自互联网转载,仅供学习交流,不得商业运营资源,不确保资源完整性,图片和资源仅供参考,不提供任何技术服务。
本站资源仅供本地编辑研究学习参考,禁止未经资源商正版授权参与任何商业行为,违法行为!如需商业请购买各资源商正版授权
本站仅收集资源,提供用户自学研究使用,本站不存在私自接受协助用户架设游戏或资源,非法运营资源行为。
 
在线客服
点击这里给我发消息 点击这里给我发消息 点击这里给我发消息
售前咨询热线
312337667

微信扫一扫,私享最新原创实用干货

QQ|免责声明|小黑屋|依星资源网 ( 鲁ICP备2021043233号-3 )|网站地图

GMT+8, 2025-4-30 10:45

Powered by Net188.com X3.4

邮箱:312337667@qq.com 客服QQ:312337667(工作时间:9:00~21:00)

快速回复 返回顶部 返回列表