zoukankan      html  css  js  c++  java
  • zookeeper:master选举

    • 模拟选举机器类
     1 package com.karat.cn.zookeeperAchieveLock.zkclient;
     2 
     3 import java.io.Serializable;
     4 
     5 /**
     6  * 选举的机器
     7  */
     8 public class UserCenter implements Serializable{
     9 
    10     private static final long serialVersionUID = -1776114173857775665L;
    11     private int id; //机器信息
    12 
    13     private String name;//机器名称
    14 
    15     public int getId() {
    16         return id;
    17     }
    18 
    19     public void setId(int id) {
    20         this.id = id;
    21     }
    22 
    23     public String getName() {
    24         return name;
    25     }
    26 
    27     public void setName(String name) {
    28         this.name = name;
    29     }
    30 
    31     @Override
    32     public String toString() {
    33         return "UserCenter [id=" + id + ", name=" + name + "]";
    34     }
    35  
    36 }
    View Code
    • 选举服务
      1 package com.karat.cn.zookeeperAchieveLock.zkclient;
      2 
      3 import org.I0Itec.zkclient.IZkDataListener;
      4 import org.I0Itec.zkclient.ZkClient;
      5 import org.I0Itec.zkclient.exception.ZkNodeExistsException;
      6 
      7 import java.util.concurrent.Executors;
      8 import java.util.concurrent.ScheduledExecutorService;
      9 import java.util.concurrent.TimeUnit;
     10 
     11 /**
     12  * 选举的服务
     13  */
     14 public class MasterSelector {
     15 
     16     private ZkClient zkClient;
     17 
     18     private final static String MASTER_PATH="/master"; //需要争抢的节点
     19 
     20     private IZkDataListener dataListener; //注册节点内容变化
     21 
     22     private UserCenter server;  //其他服务器
     23 
     24     private UserCenter master;  //master节点
     25 
     26     private boolean isRunning=false;
     27 
     28     ScheduledExecutorService scheduledExecutorService= Executors.newScheduledThreadPool(1);//定时任务
     29 
     30     public MasterSelector(UserCenter server,ZkClient zkClient) {
     31         System.out.println("["+server+"] 去争抢master权限");
     32         this.server = server;
     33         this.zkClient=zkClient;
     34 
     35         this.dataListener= new IZkDataListener() {
     36             @Override
     37             public void handleDataChange(String s, Object o) throws Exception {
     38 
     39             }
     40 
     41             @Override
     42             public void handleDataDeleted(String s) throws Exception {
     43                 //节点如果被删除, 发起选主操作
     44                 chooseMaster();
     45             }
     46         };
     47     }
     48 
     49     public void start(){
     50         //开始选举
     51         if(!isRunning){
     52             isRunning=true;
     53             zkClient.subscribeDataChanges(MASTER_PATH,dataListener); //注册节点事件
     54             chooseMaster();
     55         }
     56     }
     57 
     58 
     59     public void stop(){
     60         //停止
     61         if(isRunning){
     62             isRunning=false;
     63             scheduledExecutorService.shutdown();
     64             zkClient.unsubscribeDataChanges(MASTER_PATH,dataListener);
     65             releaseMaster();
     66         }
     67     }
     68 
     69 
     70     //具体选master的实现逻辑
     71     private void chooseMaster(){
     72         if(!isRunning){
     73             System.out.println("当前服务没有启动");
     74             return ;
     75         }
     76         try {
     77             zkClient.createEphemeral(MASTER_PATH, server);//创建一个临时节点
     78             master=server; //把server节点赋值给master
     79             System.out.println(master+"->我现在已经是master,你们要听我的");
     80 
     81             //定时器
     82             //master释放(master 出现故障),没2秒钟释放一次
     83             scheduledExecutorService.schedule(()->{
     84                 releaseMaster();//释放锁
     85             },2, TimeUnit.SECONDS);
     86         }catch (ZkNodeExistsException e){
     87             //创建一个临时节点抛出异常
     88             //表示master已经存在
     89             UserCenter userCenter=zkClient.readData(MASTER_PATH,true);
     90             if(userCenter==null) {
     91                 System.out.println("启动操作:");
     92                 chooseMaster(); //再次获取master
     93             }else{
     94                 master=userCenter;
     95             }
     96         }
     97     }
     98 
     99     private void releaseMaster(){
    100         //释放锁(故障模拟过程)
    101         //判断当前是不是master,只有master才需要释放
    102         if(checkIsMaster()){
    103             zkClient.delete(MASTER_PATH); //删除
    104         }
    105     }
    106 
    107 
    108     private boolean checkIsMaster(){
    109         //判断当前的server是不是master
    110         UserCenter userCenter=zkClient.readData(MASTER_PATH);
    111         if(userCenter.getName().equals(server.getName())){
    112             master=userCenter;
    113             return true;
    114         }
    115         return false;
    116     }
    117 
    118 }
    View Code
    • 选举测试
     1 package com.karat.cn.zookeeperAchieveLock.zkclient;
     2 
     3 import org.I0Itec.zkclient.ZkClient;
     4 import org.I0Itec.zkclient.serialize.SerializableSerializer;
     5 
     6 import java.io.IOException;
     7 import java.util.ArrayList;
     8 import java.util.List;
     9 import java.util.concurrent.TimeUnit;
    10 
    11 /**
    12  * master选举测试
    13  */
    14 public class MasterChooseTest {
    15 
    16     private final static String CONNECTSTRING="47.107.121.215:2181";
    17 
    18 
    19     public static void main(String[] args) throws IOException {
    20         List<MasterSelector> selectorLists=new ArrayList<>();
    21         try {
    22             for(int i=0;i<10;i++) {
    23                 ZkClient zkClient = new ZkClient(CONNECTSTRING, 5000,
    24                         5000,
    25                         new SerializableSerializer());
    26                 UserCenter userCenter = new UserCenter();
    27                 userCenter.setId(i);
    28                 userCenter.setName("客户端:" + i);
    29 
    30                 MasterSelector selector = new MasterSelector(userCenter,zkClient);
    31                 selectorLists.add(selector);
    32                 selector.start();//触发选举操作
    33                 TimeUnit.SECONDS.sleep(1);
    34             }
    35         } catch (InterruptedException e) {
    36             e.printStackTrace();
    37         } finally {
    38             for(MasterSelector selector:selectorLists){
    39                 selector.stop();
    40             }
    41         }
    42     }
    43 }
    View Code

    通过zookeeper进行master选举,就是利用zookeeper的节点特性,通过是否能够创建临时节点来判断是否选举成功,如果不能创建临时节点,则表明已有线程创建成功,那么创建成功的线程就为选举的master,当网络发生故障或其它问题导致该线程挂掉,那么zookeeper中的该临时节点也会删除,通过监听节点是否有过删除动作,重新选举新的master。

  • 相关阅读:
    Linux磁盘管理之创建磁盘分区05
    Linux磁盘管理之设备文件详解04
    Linux命令行上传文件到百度网盘
    Linux磁盘管理之元数据、文件和目录、链接文件03
    std..tr1如何传递引用类型给function
    如何判断一个点是否在矩形之内及C++的操作符重载
    C++11中部分新语法说明
    物理引擎中基于AABB碰撞盒的SAP碰撞检测
    c++动态库中对于字符类型变量的格式化处理
    从tr1中function使用看converting constructor
  • 原文地址:https://www.cnblogs.com/LJing21/p/10549851.html
Copyright © 2011-2022 走看看