Zookeeper的主备机选举

选举我们在此文中只讲Curator的两个客户端的使用:

在分布式环境中,有时我们需要一个时间点只需要一个服务,如处理订单业务,一个订单过来,我们希望是的一个订单处理服务去处理这个业务,同时将处理的结果同步至其他的服务,保持主备机之间的同步性,因此需要一个主机,多个备机,当主机down掉之后,备机能随时启动保证服务继续运行;

1、Curator的选举代码应用

   LeaderLatch 类
 org.apache.curator.framework.recipes.leader.LeaderLatch

几个重要的方法

 //开始进行抢主
void start() 
      //是否具有主权限
boolean hasLeadership()
   //释放主权限
void close()

//  Causes the current thread to wait until this instance acquires leadership unless the thread is interrupted,
// the specified waiting time elapses or the instance is closed.,
//-----尝试让实例获取leader权限,不一定成功,返回boolean
boolean await(long timeout, TimeUnit unit)

//是否抢主成功的一个监听
org.apache.curator.framework.recipes.leader.LeaderLatchListener

leaderLatch.addListener(new LeaderLatchListener() {
				
				@Override
				public void notLeader() {
					System.out.println("没有获取领导权!");
					
				}
				
				@Override
				public void isLeader() {
					System.out.println("获取领导权!");
					
				}
			});

2、测试代码:


  public class MasterLatch {
	static  int CLINET_COUNT = 10;
    static String LOCK_PATH = "/leader_latch";

    public static void main(String[] args) throws Exception {
        List<CuratorFramework> clientsList = Lists.newArrayListWithCapacity(CLINET_COUNT);
        List<LeaderLatch> leaderLatchList = Lists.newArrayListWithCapacity(CLINET_COUNT);
        //创建10个zk客户端模拟leader选举
        for (int i = 0; i < CLINET_COUNT; i++) {
            CuratorFramework client = getZkClient();
            clientsList.add(client);
            LeaderLatch leaderLatch = new LeaderLatch(client, LOCK_PATH, "CLIENT_" + i);
            leaderLatchList.add(leaderLatch);
            leaderLatch.addListener(new LeaderLatchListener() {
				
				@Override
				public void notLeader() {
					System.out.println("没有获取领导权!");
					
				}
				
				@Override
				public void isLeader() {
					System.out.println("获取领导权!");
					
				}
			});
            //必须调用start()方法来进行抢主
            leaderLatch.start();
        }
        //判断当前leader是哪个客户端
        checkLeader(leaderLatchList);

    }

    private static void checkLeader(List<LeaderLatch> leaderLatchList) throws Exception {
        //Leader选举需要时间 等待10秒
        Thread.sleep(10000);
        for (int i = 0; i < leaderLatchList.size(); i++) {
            LeaderLatch leaderLatch = leaderLatchList.get(i);
            //通过hasLeadership()方法判断当前节点是否是leader 
            if (leaderLatch.hasLeadership()) {
                System.out.println("当前leader:"+leaderLatch.getId());
                //释放leader权限 重新进行抢主
                leaderLatch.close();
                checkLeader(leaderLatchList);
            }
        }
    }

    private static CuratorFramework getZkClient() {
        String zkServerAddress = "192.168.6.2:2181";
        ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3, 5000);
        CuratorFramework zkClient = CuratorFrameworkFactory.builder()
                .connectString(zkServerAddress)
                .sessionTimeoutMs(5000)
                .connectionTimeoutMs(5000)
                .retryPolicy(retryPolicy)
                .build();
        zkClient.start();
        return zkClient;
    }


}

//LeaderLatch需要close后其他的线程才有机会获取leader权

3、 LeaderSelector应用

LeaderSelector类:

org.apache.curator.framework.recipes.leader.LeaderSelector

几个重要的方法:

//开始抢主
void start()

//释放主权后自动加入到抢主的行列
void autoRequeue()

//抢主的回调函数监听
LeaderSelectorListener

//抢主之后的逻辑处理
takeLeadership(CuratorFramework client) t


LeaderSelectorListenerAdapter

实现了接口监听与封装了客户端与zk服务器连接挂起或者断开时的处理逻辑(抛出抢主失败CancelLeadershipException)

在这里插入图片描述

4、代码上:

package com.tl.demo;

import java.util.List;

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.LeaderSelectorListener;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.shaded.com.google.common.collect.Lists;

/**
 * how to  use LeaderSelector  to implement master 
 *
 */

public class MasterLeaderSelector {
	
    //设置客户端的数量
	static int countClient=10;
	
	//设置leader的路径
	static String select_path="/selector";
	
	public static void main(String[] args) {
			List<CuratorFramework> clientList=Lists.newArrayListWithCapacity(countClient);
	        for(int i=0;i<countClient;i++) {
	        	CuratorFramework client=getClient();
	        	clientList.add(client);
	        	LeaderSelector leaderSelector=new LeaderSelector(client,select_path,new LeaderSelectorListener() {
					
					@Override
					public void stateChanged(CuratorFramework client, ConnectionState newState) {
						//失去连接是的状态
						System.out.println("Client的连接状态发生变化");
						
					}
					
					@Override
					public void takeLeadership(CuratorFramework client) throws Exception {
						//抢主成功后的业务处理逻辑
						System.out.println("获取leader的权利!");
						
					}
				});
	        	//leaderSelector 释放leader后会自动加入到抢主的行列
	        	leaderSelector.autoRequeue();
	        	leaderSelector.start();
	        	
	        }	
	}

    //create a client
	private static CuratorFramework getClient() {
		RetryPolicy policy=new ExponentialBackoffRetry(1000,3);
		CuratorFramework curatorFramework=	CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181")
		                                 .sessionTimeoutMs(1000)
		                                 .connectionTimeoutMs(3000)
		                                 .retryPolicy(policy)
		                                 .build();
		curatorFramework.start();
		return curatorFramework;
	}
		
}

实现 LeaderSelectorListenerAdapter

package com.tl.demo;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

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.retry.ExponentialBackoffRetry;
import org.apache.curator.shaded.com.google.common.collect.Lists;

public class MasterLeaderSelectorListner {

	
	 //设置客户端的数量
		static int countClient=10;
		
		//设置leader的路径
		static String select_path="/selector";
		
		public static void main(String[] args) {
				List<CuratorFramework> clientList=Lists.newArrayListWithCapacity(countClient);
		        for(int i=0;i<countClient;i++) {
		        	CuratorFramework client=getClient();
		        	clientList.add(client);
		        	SelectorClient	leaderSelector =new SelectorClient(client,select_path,"client"+i);
		        	//leaderSelector 释放leader后会自动加入到抢主的行列
		        	leaderSelector.start();
		        	
		        }	
		}

		 static class SelectorClient extends LeaderSelectorListenerAdapter implements Cloneable{
			 String nameString; 
			 LeaderSelector selector;
			
			 public SelectorClient(CuratorFramework client, String path, String name) {
				 nameString=name;
				 selector=new LeaderSelector(client, path, this);
				 selector.autoRequeue();
			}

			@Override
			public void takeLeadership(CuratorFramework client) throws Exception {
				//run waittime off leader 
				final int waitTime=(int)(5*Math.random())+1;
				Thread.sleep(TimeUnit.SECONDS.toMillis(waitTime));
			}
			 
			public void start() {
				selector.start();
			}
			
			public void close() {
				selector.close();
			}
		 }
		
	    //create a client
		private static CuratorFramework getClient() {
			RetryPolicy policy=new ExponentialBackoffRetry(1000,3);
			CuratorFramework curatorFramework=	CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181")
			                                 .sessionTimeoutMs(1000)
			                                 .connectionTimeoutMs(3000)
			                                 .retryPolicy(policy)
			                                 .build();
			curatorFramework.start();
			return curatorFramework;
		}
}

两种方法:
第一种:LeaderLatch需要使用方法close才能释放leader的权限
第二种:推荐使用具有自主释放的额权利,与平等竞争leader的权利

发布了15 篇原创文章 · 获赞 7 · 访问量 2864

猜你喜欢

转载自blog.csdn.net/xiaocaodeshengri/article/details/90202589