算法描述
假设有 N 台服务器 S = {S0, S1, S2, …, Sn},默认权重为 W = {W0, W1, W2, …, Wn},当前权重为 CW = {CW0, CW1, CW2, …, CWn}。在该算法中有两个权重,默认权重表示服务器的原始权重,当前权重表示每次访问后重新计算的权重,当前权重的出初始值为默认权重值,当前权重值最大的服务器为 maxWeightServer,所有默认权重之和为 weightSum,服务器列表为 serverList,算法可以描述为:
1、找出当前权重值最大的服务器 maxServer;
2、计算 {W0, W1, W2, …, Wn} 之和 sumBlance;
3、将 maxServer.CW = maxServer.CW - sumBlance;
4、重新计算 {S0, S1, S2, …, Sn} 的当前权重 CW,计算公式为 Sn.CW = Sn.CW + Sn.Wn
5、返回 maxServer
状态描述:
初始状态:5,2,2
配置前权重 | 选择序号 | 配置后权重 | 原始权重 | |
1 | 5,2,2 | 0 | -4,2,2 | 5,2,2 |
2 | 1,4,4 | 1 | 1,-5,4 | 5,2,2 |
3 | 6,-3,6 | 0 | -3,-3,6 | 5,2,2 |
4 | 2,-1,8 | 2 | 2,-1,-1 | 5,2,2 |
5 | 7,1,1 | 0 | -2,1,1 | 5,2,2 |
程序实现:
package com.jike.alg.bigData;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @program: jike_study
* @description:加权平滑负载均衡
* @author: dyingstraw
* @create: 2019-07-05 10:01
**/
public class AvgLoadBalance {
class LoadServer{
/**
* 当前权重
*/
private int currentWeight;
/**
* 原始权重
*/
private int originWeight;
/**
* 服务名
*/
private String name;
public LoadServer( String name,int currentWeight) {
this.currentWeight = currentWeight;
this.originWeight = currentWeight;
this.name = name;
}
public int getCurrentWeight() {
return currentWeight;
}
public void setCurrentWeight(int currentWeight) {
this.currentWeight = currentWeight;
}
public int getOriginWeight() {
return originWeight;
}
public void setOriginWeight(int originWeight) {
this.originWeight = originWeight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"classname\":\"LoadServer\",");
sb.append("\"currentWeight\":")
.append(currentWeight);
sb.append(",\"originWeight\":")
.append(originWeight);
sb.append(",\"name\":\"")
.append(name).append('\"');
sb.append('}');
return sb.toString();
}
}
private Map<String,LoadServer> serverMap = new ConcurrentHashMap<>();
public void initServerWeight(){
serverMap.put("101",new LoadServer("101",5));
serverMap.put("102",new LoadServer("102",2));
serverMap.put("103",new LoadServer("103",2));
}
/**
* 选择最优负载
* @return
*/
public LoadServer selectBestServer(){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("\t");
for (Map.Entry<String,LoadServer> server:serverMap.entrySet()){
stringBuilder.append(server.getValue().currentWeight+",");
}
stringBuilder.append("\t\t");
System.out.println("\t配置前\t\t配置后\t最优配置名称");
int sumBalance = 0;
LoadServer maxServer=null;
for (Map.Entry<String,LoadServer> server:serverMap.entrySet()){
/** 求总负载 **/
sumBalance+=server.getValue().originWeight;
/** 求当前时刻最大权重的负载 **/
if (maxServer==null){
maxServer = server.getValue();
}else {
if (server.getValue().getCurrentWeight()>maxServer.getCurrentWeight()){
maxServer = server.getValue();
}
}
}
/** 找到最大负载之后,恒心当前负载 **/
maxServer.setCurrentWeight(maxServer.getCurrentWeight()-sumBalance);
for (Map.Entry<String,LoadServer> server:serverMap.entrySet()){
server.getValue().setCurrentWeight(server.getValue().getCurrentWeight()+server.getValue().getOriginWeight());
stringBuilder.append(server.getValue().getCurrentWeight()+",");
}
stringBuilder.append("\t"+maxServer.getName());
System.out.println(stringBuilder);
System.out.println("--------------------------------\n");
return maxServer;
}
public static void main(String[] args) {
AvgLoadBalance balance = new AvgLoadBalance();
balance.initServerWeight();
for (int i =0;i<10;i++){
balance.selectBestServer();
}
}
}
执行结果
"D:\Program Files\Java\jdk1.8.0_121\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=12734:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_121\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\zipfs.jar;D:\Pro