引言
随着公司业务的飞速发展,以及业务的多样性,用户数会迅猛增长,系统的流量会越来越大。因此,大规模的并发用户访问会对系统的处理能力造成巨大的压力,系统必须要有足够强的处理能力才能应对。
这篇文章就来介绍一下高并发系统的通用设计原则之一:负载均衡。
什么是负载均衡
负载均衡,英文名称为 Load Balance,它的核心思想就是在用户和服务器中间加一层负载均衡服务,该层服务通过相应的负载均衡算法,将用户请求分发给应用服务器集群。
以前的单体应用时代:
随着用户规模不断扩大,单机对外提供服务越发显得力不从心:
集群时代:
常见的负载均衡服务器有:LVS、Nginx、Haproxy
负载均衡服务器会根据 应用服务器的健康状态来判断当前节点是否可以被转发,依次来保证整个应用系统的可用性。
常见的负载均衡算法包括:
- 随机算法
- 轮询算法
- 加权随机算法
- 加权轮询算法
- IP-Hash 算法
- 最小活跃连接算法
几种常见的负载均衡算法
定义两个个公用类 IpInfo、ServerRegister ,用来表示 IP 节点信息以及 IP 信息的存储。
package com.markus.service.load.balanced;
/**
* @author: markus
* @date: 2024/2/25 1:49 PM
* @Description:
* @Blog: https://markuszhang.com
* It's my honor to share what I've learned with you!
*/
public class IpInfo {
private String ipAddr;
private Integer weight;
private Integer activeLink;
public IpInfo(String ipAddr, Integer weight) {
this.ipAddr = ipAddr;
this.weight = weight;
this.activeLink = 0;
}
public String getIpAddr() {
return ipAddr;
}
public void setIpAddr(String ipAddr) {
this.ipAddr = ipAddr;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public Integer getActiveLink() {
return activeLink;
}
public void setActiveLink(Integer activeLink) {
this.activeLink = activeLink;
}
@Override
public String toString() {
return "IpInfo{" +
"ipAddr='" + ipAddr + '\'' +
", weight=" + weight +
", activeLink=" + activeLink +
'}';
}
}
package com.markus.service.load.balanced;
import java.util.HashMap;
import java.util.Map;
/**
* @author: markus
* @date: 2024/2/25 2:05 PM
* @Description:
* @Blog: https://markuszhang.com
* It's my honor to share what I've learned with you!
*/
public class ServerRegister {
public static final Map<String, IpInfo> ipInfoMap = new HashMap<>();
static {
ipInfoMap.put("192.168.163.1", new IpInfo("192.168.163.1", 1));
ipInfoMap.put("192.168.163.2", new IpInfo("192.168.163.2", 2));
ipInfoMap.put("192.168.163.3", new IpInfo("192.168.163.3", 3));
ipInfoMap.put("192.168.163.4", new IpInfo("192.168.163.4", 4));
}
}
随机算法
随机算法就是在可用的应用服务器节点中随机选择一个节点来访问。例如当前有 4 个 IP 节点,那么通过随机算法每次随机生成一个 [0,size) 范围内的随机数,然后就可以得到要访问的节点,代码如下所示:
package com.markus.service.load.balanced;
import java.util.*;
/**
* @author: markus
* @date: 2024/2/25 1:35 PM
* @Description: 随机算法
* @Blog: https://markuszhang.com
* It's my honor to share what I've learned with you!
*/
public class RandomAlgorithm {
private static Map<String