1、负载均衡算法简介和实现
1.1、随机
通过随机算法,根据后端服务器的列表随机选取其中的一台服务器进行访问
@Component
public class RandomStrategy implements LoadBalanceStrategy {
@Override
public String load(List<String> uris) {
// 0~bound(不包含)之间的随机数
int randomNumber = new Random().nextInt(uris.size());
return uris.get(randomNumber);
}
}
1.2、轮询
将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载;
@Component
public class RoundRobinStrategy implements LoadBalanceStrategy {
/**
* 定义原子计数类
*/
private AtomicInteger index = new AtomicInteger(0);
@Override
public String load(List<String> uris) {
return uris.get(Math.abs(index.incrementAndGet() % uris.size()));
}
}
1.3、加权随机
加权随机法根据后端机器的配置,系统的负载分配不同的权重。随机获取服务器进行转发请求,本质上就是按照权重往列表多放了数据,但是还是随机的。
@Component
public class RandomWeightStrategy implements LoadBalanceStrategy {
@Override
public String load(List<String> uris) {
// 0~bound(不包含)之间的随机数
int randomNumber = new Random().nextInt(uris.size());
return uris.get(randomNumber);
}
public String load(List<String> uris,List<Integer> weights) {
// 构建加权list
List<String> weightUris = new ArrayList<>();
if(uris.size() != weights.size()){
throw new RuntimeException("转发服务器列表需和权重列表数量一致");
}
for (int i = 0; i < uris.size(); i++) {
Integer weight = weights.get(i);
if(weight<=0){
continue;
}
for (int j = 0; j < weight; j++) {
weightUris.add(uris.get(i));
}
}
// 0~bound(不包含)之间的随机数
int randomNumber = new Random().nextInt(weightUris.size());
return uris.get(randomNumber);
}
}
1.4、加权轮询
同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端;
public class RoundRobinWeightStrategy implements LoadBalanceStrategy{
/**
* 定义原子计数类
*/
private AtomicInteger index = new AtomicInteger(0);
@Override
public String load(List<String> uris) {
return uris.get(Math.abs(index.incrementAndGet() % uris.size()));
}
public String load(List<String> uris,List<Integer> weights) {
// 构建加权list
List<String> weightUris = new ArrayList<>();
if(uris.size() != weights.size()){
throw new RuntimeException("转发服务器列表需和权重列表数量一致");
}
for (int i = 0; i < uris.size(); i++) {
Integer weight = weights.get(i);
if(weight<=0){
continue;
}
for (int j = 0; j < weight; j++) {
weightUris.add(uris.get(i));
}
}
return uris.get(Math.abs(index.incrementAndGet() % uris.size()));
}
}
1.5、IpHash
通过请求ip进行hash,可以让服务器列表处理请求更加均衡
@Component
public class IpHashStrategy implements LoadBalanceStrategy {
@Override
public String load(List<String> uris) {
return null;
}
public String load(List<String> uris, String ip) {
return uris.get(ip.hashCode() % uris.size());
}
}