这里是负载均衡的常见算法。
1 轮询算法(Round-Robin)
轮询算法是最简单的一种负载均衡算法。它的原理是把来自用户的请求轮流分配给内部的服务器:从服务器1开始,直到服务器N,然后重新开始循环。
代码:
// 轮询
public Server round() {
currentIndex = (currentIndex + 1) % totalServer;
return servers.get(currentIndex);
}
其中currentindex是当前位置,totalserver是所有服务器节点数量。
优点:简单
缺点:各节点处理能力不同。
2. 加权轮询算法(WeightedRound-Robin)
轮询算法并没有考虑每台服务器的处理能力,实际中可能并不是这种情况。由于每台服务器的配置、安装的业务应用等不同,其处理能力会不一样。所以,加权轮询算法的原理就是:根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。
这里又有两种,一种是普通加权,类似于一个数组,按权重大小排序。优先获取大权重的节点。
缺点:是不平滑。
还有一种平滑加权轮询实现,除依赖权重weight外,还依赖当前权重current_weight。是个可变数值。
思路:初始化时,获取节点的大小,及节点全部权重的最大公约数gcd,最大权重数。
遍历列表, 获取当前权重,如果current_weight-权重最大公约数gcd<=0.则当前权重为最大权重。
判断当前节点的权重》=当前权重,则返回对应节点,否则遍历下一个节点。
因为是循环遍历:每次从max_weight步进递减去gcd.获取出节点权重大于这个的节点。所以是平滑的,分布相对均匀的。
代码:server类 代码来自:http://m635674608.iteye.com/blog/2396303
package com.daojia.math;
public class Server {
private String ip;
private int weight;
public Server(String ip) {
super();
this.ip = ip;
}
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 String toString() {
return "Server [ip=" + ip + ", weight=" + weight + "]";
}
}
主代码:
package com.daojia.math;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class WeightRoundRobin {
private List<Server> servers;
private int currentIndex;
private int totalServer;
private int currentWeight;
private int maxWeight;
private int gcdWeight;
public WeightRoundRobin() {
servers = new ArrayList<>();
servers.add(new Server("192.168.1.2", 5));
servers.add(new Server("192.168.1.3", 10));
servers.add(new Server("192.168.1.4", 15));
servers.add(new Server("192.168.1.5", 100));
servers.add(new Server("192.168.1.6", 5));
servers.add(new Server("192.168.1.7", 20));
servers.add(new Server("192.168.1.8", 30));
totalServer = servers.size();
currentIndex = totalServer - 1;
maxWeight = maxWeight();
gcdWeight = serverGcd();
}
/**
* 遍历全部节点,从最大的权重开始取。
* 每次权重-公约数递减。
* 如果当前权重《=0.则从循环从最大权重开始。
* @return
*/
public Server round() {
while (true) {
currentIndex = (currentIndex + 1) % totalServer;
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);
}
}
}
/**
* 返回所有服务器的权重的最大公约数
*
* @return
*/
private int serverGcd() {
int comDivisor = 0;
for (int i = 0; i < totalServer - 1; i++) {
if (comDivisor == 0) {
comDivisor = gcd(servers.get(i).getWeight(), servers.get(i + 1).getWeight());
} else {
comDivisor = gcd(comDivisor, servers.get(i + 1).getWeight());
}
}
return comDivisor;
}
/**
* 获得服务器中的最大权重
*
* @return
*/
private int maxWeight() {
int max = servers.get(0).getWeight();
int tmp;
for (int i = 1; i < totalServer; i++) {
tmp = servers.get(i).getWeight();
if (max < tmp) {
max = tmp;
}
}
return max;
}
/**
* 求两个数的最大公约数 4和6最大公约数是2
*
* @param num1
* @param num2
* @return
*/
private int gcd(int num1, int num2) {
BigInteger i1 = new BigInteger(String.valueOf(num1));
BigInteger i2 = new BigInteger(String.valueOf(num2));
return i1.gcd(i2).intValue();
}
public static void main(String[] args) {
final WeightRoundRobin wr = new WeightRoundRobin();
// 非并发情况
for (int i = 0; i < 100; i++) {
System.out.println(wr.round());
}
System.out.println();
System.out.println("==========");
System.out.println();
final CyclicBarrier b = new CyclicBarrier(30);
// 并发情况
for (int i = 0; i < 30; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
b.await();
System.out.println(Thread.currentThread().getName() + " " + wr.round());
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}, "thread" + i).start();
}
}
}
运行结果:
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.3, weight=10]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.2, weight=5]
Server [ip=192.168.1.3, weight=10]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.6, weight=5]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.3, weight=10]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.2, weight=5]
Server [ip=192.168.1.3, weight=10]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.6, weight=5]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.4, weight=15]
Server [ip=192.168.1.5, weight=100]
Server [ip=192.168.1.7, weight=20]
Server [ip=192.168.1.8, weight=30]
Server [ip=192.168.1.3, weight=10]
==========
thread27 Server [ip=192.168.1.4, weight=15]
thread0 Server [ip=192.168.1.5, weight=100]
thread4 Server [ip=192.168.1.8, weight=30]
thread1 Server [ip=192.168.1.7, weight=20]
thread29 Server [ip=192.168.1.5, weight=100]
thread28 Server [ip=192.168.1.5, weight=100]
thread25 Server [ip=192.168.1.5, weight=100]
thread24 Server [ip=192.168.1.5, weight=100]
thread21 Server [ip=192.168.1.5, weight=100]
thread20 Server [ip=192.168.1.5, weight=100]
thread17 Server [ip=192.168.1.8, weight=30]
thread16 Server [ip=192.168.1.7, weight=20]
thread13 Server [ip=192.168.1.6, weight=5]
thread12 Server [ip=192.168.1.5, weight=100]
thread9 Server [ip=192.168.1.4, weight=15]
thread8 Server [ip=192.168.1.3, weight=10]
thread5 Server [ip=192.168.1.2, weight=5]
thread2 Server [ip=192.168.1.5, weight=100]
thread3 Server [ip=192.168.1.5, weight=100]
thread6 Server [ip=192.168.1.5, weight=100]
thread7 Server [ip=192.168.1.5, weight=100]
thread11 Server [ip=192.168.1.5, weight=100]
thread10 Server [ip=192.168.1.5, weight=100]
thread14 Server [ip=192.168.1.5, weight=100]
thread15 Server [ip=192.168.1.5, weight=100]
thread18 Server [ip=192.168.1.5, weight=100]
thread19 Server [ip=192.168.1.8, weight=30]
thread22 Server [ip=192.168.1.5, weight=100]
thread23 Server [ip=192.168.1.8, weight=30]
thread26 Server [ip=192.168.1.5, weight=100]
参考:http://m635674608.iteye.com/blog/2396303