权重轮询算法

相信熟悉过Nginx的都知道,Nginx其中有一个功能是负载均衡。

Nginx的负载均衡里可以配置一个服务器列表,如:

upstream detecotr_server {
		    #ip_hash;  
				#这里指定多个源服务器,ip:端口,80端口的话可写可不写  
				server 192.168.154.1:8080 weight=1;# max_fails=2 fails_time=2;  
				server 192.168.154.2:8088 weight=2;# max_fail2=2 fails_time=2;  
		} 
当负载均衡策略为加权轮询,如果的3个请求,则会有1个请求分发到192.168.154.1服务器上,2个请求分发到192.168.154.2服务器上。加权轮询的算法实现以下:

java实现

public class WeightRoundRobin {
	
	/**上次选择的服务器*/
	private int currentIndex = -1;
	/**当前调度的权值*/
	private int currentWeight = 0;
	/**最大权重*/
	private int maxWeight;
	/**权重的最大公约数*/
	private int gcdWeight;
	/**服务器数*/
	private int serverCount;
	private List<Server> servers = new ArrayList<Server>();
	
	public int greaterCommonDivisor(int a, int b){
		BigInteger aBig = new BigInteger(String.valueOf(a));
		BigInteger bBig = new BigInteger(String.valueOf(b));
		return aBig.gcd(bBig).intValue();
	}
	
	public int greatestCommonDivisor(List<Server> servers){
		int divisor = 0;
		for(int index = 0, len = servers.size(); index < len - 1; index++){
			if(index ==0){
				divisor = greaterCommonDivisor(
							servers.get(index).getWeight(), servers.get(index + 1).getWeight());
			}else{
				divisor = greaterCommonDivisor(divisor, servers.get(index).getWeight());
			}
		}
		return divisor;
	}
	
	public int greatestWeight(List<Server> servers){
		int weight = 0;
		for(Server server : servers){
			if(weight < server.getWeight()){
				weight = server.getWeight();
			}
		}
		return weight;
	}
	
	/**
    *  算法流程: 
    *  假设有一组服务器 S = {S0, S1, …, Sn-1}
    *  有相应的权重,变量currentIndex表示上次选择的服务器
    *  权值currentWeight初始化为0,currentIndex初始化为-1 ,当第一次的时候返回 权值取最大的那个服务器,
    *  通过权重的不断递减 寻找 适合的服务器返回,直到轮询结束,权值返回为0 
    */
	public Server getServer(){
		while(true){
			currentIndex = (currentIndex + 1) % serverCount;
			if(currentIndex == 0){
				currentWeight = currentWeight - gcdWeight;
				if(currentWeight <= 0){
					currentWeight = maxWeight;
					if(currentWeight == 0){
						return null;
					}
				}
			}
			if(servers.get(currentIndex).getWeight() >= currentWeight){
				return servers.get(currentIndex);
			}
		}
	}
	
	public void init(){
		servers.add(new Server("192.168.1.101", 1));
		servers.add(new Server("192.168.1.102", 2));
		servers.add(new Server("192.168.1.103", 3));
		servers.add(new Server("192.168.1.104", 4));
		servers.add(new Server("192.168.1.105", 5));
		
		maxWeight = greatestWeight(servers);
		gcdWeight = greatestCommonDivisor(servers);
		serverCount = servers.size();
	}
	
	public static void main(String[] args){
		WeightRoundRobin weightRoundRobin = new WeightRoundRobin();
		weightRoundRobin.init();
		
		for(int i = 0; i < 15; i++){
			Server server = weightRoundRobin.getServer();
			System.out.println("server " + server.getIp() + " weight=" + server.getWeight());
		}
	}

}

class Server{
	private String ip;
	
	private int weight;
	
	public Server(String ip, int weight) {
		this.ip = ip;
		this.weight = weight;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj) return true;
		
		if(obj instanceof Server){
			Server server = (Server)obj;
		
			return getIp().equals(server.getIp());
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		return getIp().hashCode();
	}
	
}

结果:

server 192.168.1.105 weight=5
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.102 weight=2
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.101 weight=1
server 192.168.1.102 weight=2
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5


另,使用加权随机数来实现加权轮询算法点击打开链接


转自:

http://www.cnblogs.com/huligong1234/p/3819979.html

http://www.cnblogs.com/huligong1234/p/3862665.html


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值