18.9.6 负载均衡算法与实现策略
1. 负载均衡基础概念
1.1 负载均衡原理
public class LoadBalancingPrinciple {
/*
* 负载均衡核心概念:
*
* 1. 基本作用
* - 将请求分发到多个服务器
* - 提高系统吞吐量和可用性
* - 避免单点过载
*
* 2. 实现层次
* - 硬件负载均衡 (F5, A10)
* - 软件负载均衡 (Nginx, HAProxy)
* - 应用层负载均衡 (Ribbon, Dubbo)
*
* 3. 常见算法
* - 轮询 (Round Robin)
* - 加权轮询 (Weighted Round Robin)
* - 随机 (Random)
* - 最少连接 (Least Connections)
* - 一致性哈希 (Consistent Hash)
*/
public void demonstrateLoadBalancing() {
System.out.println("=== 负载均衡算法演示 ===");
// 创建服务器列表
java.util.List<Server> servers = createServerList();
demonstrateRoundRobin(servers);
demonstrateWeightedRoundRobin(servers);
demonstrateRandom(servers);
demonstrateLeastConnections(servers);
demonstrateConsistentHash(servers);
}
private java.util.List<Server> createServerList() {
java.util.List<Server> servers = new java.util.ArrayList<>();
servers.add(new Server("server-1", "192.168.1.10", 8080, 100));
servers.add(new Server("server-2", "192.168.1.11", 8080, 200));
servers.add(new Server("server-3", "192.168.1.12", 8080, 150));
return servers;
}
private void demonstrateRoundRobin(java.util.List<Server> servers) {
System.out.println("--- 轮询算法演示 ---");
RoundRobinLoadBalancer roundRobin = new RoundRobinLoadBalancer(servers);
System.out.println("连续5次请求分发:");
for (int i = 1; i <= 5; i++) {
Server selected = roundRobin.select();
System.out.println(" 请求" + i + " -> " + selected.getName());
}
System.out.println("轮询: 平均分配,简单公平\n");
}
private void demonstrateWeightedRoundRobin(java.util.List<Server> servers) {
System.out.println("--- 加权轮询算法演示 ---");
WeightedRoundRobinLoadBalancer weightedRR = new WeightedRoundRobinLoadBalancer(servers);
System.out.println("连续10次请求分发 (权重 1:2:1.5):");
for (int i = 1; i <= 10; i++) {
Server selected = weightedRR.select();
System.out.println(" 请求" + i + " -> " + selected.getName() + " (权重:" + selected.getWeight() + ")");
}
System.out.println("加权轮询: 按权重分配,性能差异化\n");
}
private void demonstrateRandom(java.util.List<Server> servers) {
System.out.println("--- 随机算法演示 ---");
RandomLoadBalancer random = new RandomLoadBalancer(servers);
System.out.println("连续5次请求分发:");
for (int i = 1; i <= 5; i++) {
Server selected = random.select();
System.out.println(" 请求" + i + " -> " + selected.getName());
}
System.out.println("随机: 简单实现,长期均匀\n");
}
private void demonstrateLeastConnections(java.util.List<Server> servers) {
System.out.println("--- 最少连接算法演示 ---");
LeastConnectionsLoadBalancer leastConn = new LeastConnectionsLoadBalancer(servers);
System.out.println("模拟连接变化:");
for (int i = 1; i <= 5; i++) {
Server selected = leastConn.select();
selected.incrementConnections();
System.out.println(" 请求" + i + " -> " + selected.getName() + " (连接数:" + selected.getConnections() + ")");
}
System.out.println("最少连接: 动态负载感知\n");
}
private void demonstrateConsistentHash(java.util.List<Server> servers) {
System.out.println("--- 一致性哈希算法演示 ---");
ConsistentHashLoadBalancer consistentHash = new ConsistentHashLoadBalancer(servers);
System.out.println("相同key的请求分发:");
String[] keys = {"user:123", "user:456", "user:123", "user:789", "user:123"};
for (int i = 0; i < keys.length; i++) {
Server selected = consistentHash.select(keys[i]);
System.out.println(" " + keys[i] + " -> " + selected.getName());
}
System.out.println("一致性哈希: 相同key固定路由\n");
}
}
// 服务器类
class Server {
private String name;
private String host;
private int port;
private int weight;
private int connections;
private boolean healthy;
public Server(String name, String host, int port, int weight) {
this.name = name;
this.host = host;
this.port = port;
this.weight = weight;
this.connections = 0;
this.healthy = true;
}
public String getName() { return name; }
public String getHost() { return host; }
public int getPort() { return port; }
public int getWeight() { return weight; }
public int getConnections() { return connections; }
public boolean isHealthy() { return healthy; }
public void incrementConnections() { this.connections++; }
public void decrementConnections() { this.connections--; }
public void setHealthy(boolean healthy) { this.healthy = healthy; }
}
// 轮询负载均衡器
class RoundRobinLoadBalancer {
private java.util.List<Server> servers;
private java.util.concurrent.atomic.AtomicInteger counter = new java.util.concurrent.atomic.AtomicInteger(0);
public RoundRobinLoadBalancer(java.util.List<Server> servers) {
this.servers = new java.util.ArrayList<>(servers);
}
public Server select() {
if (servers.isEmpty()) {
return null;
}
int index = counter.getAndIncrement() % servers.size();
return servers.get(index);
}
}
// 加权轮询负载均衡器
class WeightedRoundRobinLoadBalancer {
private java.util.List<Server> servers;
private java.util.List<WeightedServer> weightedServers;
public WeightedRoundRobinLoadBalancer(java.util.List<Server> servers) {
this.servers = servers;
this.weightedServers = new java.util.ArrayList<>();
for (Server server : servers) {
weightedServers.add(new WeightedServer(server, server.getWeight(), 0));
}
}
public Server select() {
if (weightedServers.isEmpty()) {
return null;
}
int totalWeight = weightedServers.stream().mapToInt(ws -> ws.getWeight()).sum();
// 增加当前权重
for (WeightedServer ws : weightedServers) {
ws.setCurrentWeight(ws.getCurrentWeight() + ws.getWeight());
}
// 选择当前权重最大的服务器
WeightedServer selected = weightedServers.stream()
.max((ws1, ws2) -> Integer.compare(ws1.getCurrentWeight(), ws2.getCurrentWeight()))
.orElse(null);
if (selected != null) {
selected.setCurrentWeight(selected.getCurrentWeight() - totalWeight);
return selected.getServer();
}
return null;
}
}
// 加权服务器
class WeightedServer {
private Server server;
private int weight;
private int currentWeight;
public WeightedServer(Server server, int weight, int currentWeight) {
this.server = server;
this.weight = weight;
this.currentWeight = currentWeight;
}
public Server getServer() { return server; }
public int getWeight() { return weight; }
public int getCurrentWeight() { return currentWeight; }
public void setCurrentWeight(int currentWeig
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java面试圣经 文章被收录于专栏
Java面试圣经,带你练透java圣经
