负载均衡--zookpeer之轮询算法

1  Ngix 和 dubbo的负载均衡的区别?

   Ngix负责前端的负载均衡,zookeeper负责后台的dubbo的rpc的集群的负载均衡

2 代码实现

      监听者

import java.io.IOException;

import org.apache.log4j.Logger;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class WatchMore
{
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(WatchMore.class);

	// 定义常量
	private static final String CONNECTSTRING = "192.168.10.167:2181";
	private static final int SESSION_TIMEOUT = 50 * 1000;
	private static final String PATH = "/atguigu";
	// 定义实例变量
	private ZooKeeper zk = null;
	private String oldValue = "";

	public ZooKeeper startZK() throws IOException
	{
		return new ZooKeeper(CONNECTSTRING, SESSION_TIMEOUT, new Watcher() {
			@Override
			public void process(WatchedEvent event)
			{
			}
		});

	}

	public void createZNode(String nodePath, String nodeValue) throws KeeperException, InterruptedException
	{
		zk.create(nodePath, nodeValue.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
	}

	public String getZNode(String nodePath) throws KeeperException, InterruptedException
	{
		String result = "";
		
		byte[] byteArray = zk.getData(nodePath, new Watcher() {
			@Override
			public void process(WatchedEvent event)
			{
				try {
					triggerValue(nodePath);
				}
				catch (KeeperException | InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, new Stat());
		
		result = new String(byteArray);
		oldValue = result;
		
		return result;
	}

	public boolean triggerValue(String nodePath) throws KeeperException, InterruptedException
	{
		String result = "";

		byte[] byteArray = zk.getData(nodePath, new Watcher() {
			@Override
			public void process(WatchedEvent event)
			{
				try {
					triggerValue(nodePath);
				}
				catch (KeeperException | InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, new Stat());

		result = new String(byteArray);

		String newValue = result;

		if (oldValue.equals(newValue)) {
			logger.info("**************no change****************");
			return false;
		}
		else {
			logger.info("**************oldValue:" + oldValue + "\t newValue: " + newValue);
			oldValue = newValue;
			return true;
		}
	}

	public static void main(String[] args) throws IOException, KeeperException, InterruptedException
	{
		WatchMore myWatch = new WatchMore();

		// 1 获得zk实例
		myWatch.setZk(myWatch.startZK());

		if (myWatch.getZk().exists(PATH, false) == null) 
		{
			String initValue = "AAA";
			myWatch.createZNode(PATH, initValue);

			logger.info("***************main: " + myWatch.getZNode(PATH));

			Thread.sleep(Long.MAX_VALUE);

		}else {
			logger.info("***************have node*******");
		}
	}

	// setter------getter
	public ZooKeeper getZk()
	{
		return zk;
	}

	public void setZk(ZooKeeper zk)
	{
		this.zk = zk;
	}

	public String getOldValue()
	{
		return oldValue;
	}

	public void setOldValue(String oldValue)
	{
		this.oldValue = oldValue;
	}

}

3    实现负载均衡的服务

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


import org.apache.log4j.Logger;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import com.atguigu.zk.watch.WatchMore;
public class BalanceTest 
{
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(WatchMore.class);
	// 定义常量
	private static final String CONNECTSTRING = "192.168.31.167:2181";
	private static final int SESSION_TIMEOUT = 50 * 1000;
	private static final String PATH = "/atcunzi";
	private static final String SUB_PREFIX = "sub";
	// 定义实例变量
	private ZooKeeper zk = null;   
	private List<String> serviceLists = new ArrayList<String>(); // sub1,.....sub5  // 用来收集可用服务的
	private int subCount = 5;  // 可用服务个数
	private int currentServiceNum = 0;  // 当前请求序号
	// 初始化zookeepr,并获取服务的集合
	public ZooKeeper startZK() throws IOException
	{
		return new ZooKeeper(CONNECTSTRING, SESSION_TIMEOUT,new Watcher() {
			@Override
			public void process(WatchedEvent event)
			{
				try 
				{
					serviceLists = zk.getChildren(PATH,true);
				}catch (KeeperException | InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	//  处理轮询算法逻辑  重要的是怎么能让服务 轮询
	public String dealRquest() throws KeeperException, InterruptedException
	{
		currentServiceNum = currentServiceNum + 1;
		
		for (int i = currentServiceNum; i <=subCount; i++) 
		{
			if(serviceLists.contains(SUB_PREFIX+currentServiceNum))
			{
				return new String(zk.getData(PATH+"/"+SUB_PREFIX+currentServiceNum,false,new Stat()));
			}else{
				currentServiceNum = currentServiceNum + 1;
			}
		}
		//重要的是怎么能让服务 轮询 1  3  5 currentServiceNum = 6
		for (int i = 1; i <=subCount; i++) 
		{
			if(serviceLists.contains(SUB_PREFIX+i))
			{
				currentServiceNum = i;
				return new String(zk.getData(PATH+"/"+SUB_PREFIX+currentServiceNum,false,new Stat()));				
			}
		}
		return "no subNode~~~~~";
	}

	public static void main(String[] args) throws IOException, InterruptedException
	{
		BalanceTest test = new BalanceTest();
		
		test.setZk(test.startZK());
		Thread.sleep(3000);
		String result = null;
		for (int i = 1; i <=15; i++) 
		{
			try 
			{
				result = test.dealRquest();
				
				logger.info("*********customerID: "+i+"\t currentWindows:"+test.currentServiceNum+"\t"+result);
				
				Thread.sleep(2000);
			}
			catch (KeeperException | InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}
	///----setter=-=getter
	public ZooKeeper getZk()
	{
		return zk;
	}
	public void setZk(ZooKeeper zk)
	{
		this.zk = zk;
	}
}

	

4  总结

     负载均衡可以看成一个银行,请求看成是顾客,后台服务看成是银行柜台,大堂经理可以看成zookeeper

     服务启动的时候,需要先准备各个银行柜台都准备好,当顾客来到时候,可以 通过大堂经理的指引,去到相应的柜台进行柜台处理。

    难点:当一个柜台暂停服务时候,大唐经理怎么知道的,并且怎么分发处理,并且服务怎么轮询的?

5   maven配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.atguigu.zk1014</groupId>
	<artifactId>zk1014</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>zk1014</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
		<dependency>
			<groupId>com.101tec</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.10</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.9</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

猜你喜欢

转载自blog.csdn.net/qq_35703121/article/details/80948511