zoukankan      html  css  js  c++  java
  • 负载均衡实现之随机数

    负载均衡(LoadBalance),它的职责是将网络请求,或者其他形式的负载“均摊”到不同的机器上。避免集群中部分服务器压力过大,而另一些服务器比较空闲的情况。通过负载均衡,可以让每台服务器获取到适合自己处理能力的请求。

    ​ 常见的负载均衡的实现方法有多种,如随机、轮询、hash一致性等。本文使用随机法实现负载均衡。

    ​ 随机数法就是几个数中随机获取一个数字,然后获取这个数据对应的服务器。

    /**
     * 服务器类
     */
    public class Server {
    	
    	private String serverName;
    	
    	public Server(String name) {
    		this.serverName = name;
    	}
    	
    	public String getServerName() {
    		return serverName;
    	}
    	public void setServerName(String serverName) {
    		this.serverName = serverName;
    	}
    
    	@Override
    	public String toString() {
    		return "Server{serverName:"+this.getServerName()+"}";
    	}
    }
    
    public class LoadBalance_Random {
    	//用来存放所有的服务器
    	static List<Server> ServerList = new ArrayList<Server>();
    	//随机数生成器
    	private static final Random r = new Random();
    	
    	//初始化   模拟集群中提供服务的服务器
    	static{
    		Server server1 = new Server("server1");
    		Server server2 = new Server("server2");
    		Server server3 = new Server("server3");
    		ServerList.add(server1);
    		ServerList.add(server2);
    		ServerList.add(server3);
    	}
    	
    	public static void main(String[] args) {
    		//模拟10个请求来获取对应的服务器
    		for(int i=0;i<10;i++){
    			Server server_random = doSelect(ServerList);
    			System.out.println(server_random);
    		}
    	}
    
    	/**
    	 * 选择服务器
    	 * @param serverList
    	 * @return
    	 */
    	private static Server doSelect(List<Server> serverList) {
    		Server server = null;
    		//服务器的个数
    		int serverNum = serverList.size();
    		//随机获取一个
    		int serverIndex = r.nextInt(serverNum);
    		server = serverList.get(serverIndex);
    		return server;
    	}
    }
    

    ​ 执行main方法测试,结果如下:

    ​ 在每台服务器的配置性能等各方面都一样时,使用这种随机方法也是可取的,因为每台服务器获取的要处理的请求的数据量的概率是一样的。但是有时候,我们的服务器不一定都是相同的配置,每一台服务器的性能都有一定的差异性,导致服务器提供服务的能力的差异,比如上边我们有3台服务器,Server1每秒可处理5个请求,Server2每秒只能处理3个请求,Server3每秒只能处理2个请求,此时如果我们有10个请求过来了,我们分别给3个Server3个请求处理,由于Server3只能处理2个请求,这时就会导致服务3不可用。

    ​ 对这种不同服务能力的服务实现负载均衡,我们可以使用加权随机法。对每个服务标记权重,提高处理能力强的服务器的权重,降低服务能力若的服务器的权重,即根据能力的大小分配对应比例的请求数。

    ​ 修改上述代码,给服务加权重

    /**
     * 服务器类
     */
    public class Server {
    	
    	private String serverName;
    	private int weight;//权重
    	
    	public Server(String name, int weight) {
    		this.serverName = name;
    		this.weight = weight;
    	}
    	
    	@Override
    	public String toString() {
    		return "Server{serverName:"+this.getServerName()+",weight:"+this.getWeight()+"}";
    	}
    	
    	// 省略getter 和 setter方法
    }
    

    ​ 初始化时指定服务器的权重

    	//初始化   模拟集群中提供服务的服务器
    	static{
    		Server server1 = new Server("server1", 5);
    		Server server2 = new Server("server2", 3);
    		Server server3 = new Server("server3", 2);
    		ServerList.add(server1);
    		ServerList.add(server2);
    		ServerList.add(server3);
    	}
    

    ​ 根据权重值获取服务

    private static Server doSelectWithWeight(List<Server> serverList) {
    		Server server = null;
    		int totalWeight = 0; //所有服务器的总权重
    		boolean isSame = true;//默认所有服务器的权重都相同
    		
    		for(int i=0; i<serverList.size(); i++){
    			//获取当前服务器得权重
    			int serverWeight = serverList.get(i).getWeight();
    			//权重累加
    			totalWeight = totalWeight + serverWeight;
    			//i = 0时默认还是权重都一样
    			//从第二个开始检测每个服务器得权重是不是都一样,只需要与它得前一个服务得权重相比就可以了
    			if(isSame && i>0){
    				int preServerWeight = serverList.get(i-1).getWeight();
    				if(serverWeight != preServerWeight){//当前服务器权重和前一个服务器得权重不相同
    					isSame = false;
    				}
    			}
    		}
    		
    		if(!isSame){//服务器得权重不是都一样
    			//在总权重下获取一个随机数 
    			int index = r.nextInt(totalWeight);
    			//
    			for(int i=0;i<serverList.size();i++){
    				int serverWeight = serverList.get(i).getWeight();
    				//判断获取得随机数落在总权重得哪一个区间
    				//3台服务器得得权重分别为5 3 2  总和为10  [0到5)这个区间属于服务器1  [5到8)这个区间属于服务器2 【8到10)这个区间属于服务器3
    				//如 获取到得随机数是6  6-5=1   大于0  说明不在服务器1得区间,遍历  1-3= -2 小于0  说明它落在了服务器2所在得区间  就可以得对应服务器
    				index = index - serverWeight;
    				if(index < 0){
    					return serverList.get(i);
    				}
    			}
    		}else{
    			//所有服务器权重都一样时,按照完全随机法随机获取一个服务器
    			server = doSelect(serverList);
    		}
    		return server;
    	}
    

    ​ 使用main方法测试

    public static void main(String[] args) {
    		//模拟20个请求获取对应的服务
    		for(int i=0;i<20;i++){
    			Server server_random_weight = doSelectWithWeight(ServerList);
    			System.out.println(server_random_weight);
    		}
    	}
    

    测试结果如下

    从测试结果图中可以看到,权重大的获取到的请求数多,相反权重小的获取到的请求数越小。

  • 相关阅读:
    DJANGO
    前端--BootStrap
    前端--JQuery
    前端--JavaScript
    前端--CSS
    前端--HTML
    python中面试题积累
    python中一些小的知识点
    python中字典的增删改查及相关知识点
    python中列表的增删改查以及其它相关方法
  • 原文地址:https://www.cnblogs.com/love-wzy/p/10718972.html
Copyright © 2011-2022 走看看