找回密码
 立即注册
首页 业界区 业界 聊聊六种负载均衡算法

聊聊六种负载均衡算法

卒挪 11 小时前
负载均衡(Load Balancing)是一种计算机网络和服务器管理技术,旨在分配网络流量、请求或工作负载到多个服务器或资源,以确保这些服务器能够高效、均匀地处理负载,并且能够提供更高的性能、可用性和可扩展性。
这篇文章,我们聊聊六种通用的负载均衡算法。
1.png

1 轮询 (Round Robin)

轮询是指将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。
2.png

示例代码:
  1. import java.util.List;
  2. import java.util.concurrent.atomic.AtomicInteger;
  3. public class RoundRobin {
  4.     private final List<String> servers;
  5.     private final AtomicInteger index = new AtomicInteger(0);
  6.     public RoundRobin(List<String> servers) {
  7.         this.servers = servers;
  8.     }
  9.     public String getServer() {
  10.         int currentIndex = index.getAndIncrement() % servers.size();
  11.         return servers.get(currentIndex);
  12.     }
  13. }
复制代码
2 粘性轮询 (Sticky Round-Robin)

粘性轮询是标准轮询算法的一个变种,它通过记住客户端与服务实例的映射关系,确保来自同一客户端的连续请求会被路由到同一个服务实例上。
它的特点是:

  • 会话保持:一旦客户端首次请求被分配到某个服务实例,后续请求会"粘"在这个实例上
  • 客户端识别:通常基于客户端IP、会话ID或特定HTTP头来识别客户端
  • 故障转移:当目标服务实例不可用时,系统会重新分配客户端到其他可用实例
3.png

示例代码:
  1. import java.util.List;
  2. import java.util.Map;
  3. import java.util.concurrent.ConcurrentHashMap;
  4. import java.util.concurrent.atomic.AtomicInteger;
  5. public class StickyRoundRobin {
  6.     private final List<String> servers;
  7.     private final AtomicInteger index = new AtomicInteger(0);
  8.     private final Map<String, String> clientToServer = new ConcurrentHashMap<>();
  9.     public StickyRoundRobin(List<String> servers) {
  10.         this.servers = servers;
  11.     }
  12.     public String getServer(String clientId) {
  13.         return clientToServer.computeIfAbsent(clientId,
  14.             k -> servers.get(index.getAndIncrement() % servers.size()));
  15.     }
  16. }
复制代码
3 加权轮询 (Weighted Round-Robin)

加权轮询是标准轮询算法的增强版本,它允许管理员为每个服务实例分配不同的权重值。权重越高的实例处理越多的请求,从而实现更精细的负载分配。
4.png

它的特点是:

  • 权重分配:每个服务实例都有对应的权重值
  • 比例分配:请求按权重比例分配到不同实例
  • 动态调整:权重可以动态修改以适应不同场景
示例代码:
  1. private static Map<String, Integer> serverMap = new ConcurrentHashMap<>();
  2. //记录服务器权重总和
  3. private static int totalWeight = 0;
  4. public static String weightRandom() {
  5.     //获取服务器数量
  6.     int serverCount = serverMap.size();
  7.     //如果没有可用的服务器返回null
  8.     if (serverCount == 0) {
  9.         return null;
  10.     }
  11.     //在此处为避免多线程并发操作造成错误,在方法内部进行锁操作
  12.     synchronized (serverMap) {
  13.         //计算服务器权重总和
  14.         for (Map.Entry<String, Integer> entry : serverMap.entrySet()) {
  15.             totalWeight += entry.getValue();
  16.         }
  17.         //生成一个随机数
  18.         int randomWeight = new Random().nextInt(totalWeight);
  19.         //遍历服务器列表,根据服务器权重值选择对应地址
  20.         for (Map.Entry<String, Integer> entry : serverMap.entrySet()) {
  21.             String serverAddress = entry.getKey();
  22.             Integer weight = entry.getValue();
  23.             randomWeight -= weight;
  24.             if (randomWeight < 0) {
  25.                 return serverAddress;
  26.             }
  27.         }
  28.     }
  29.     //默认返回null
  30.     return null;
  31. }
  32. public class WeightRandomLoadBalancer implements LoadBalancer {
  33.     private List<String> servers = new ArrayList<>();
  34.     private Map<String, Integer> weightMap = new HashMap<>();
  35.     public WeightRandomLoadBalancer(Map<String, Integer> servers) {
  36.         this.servers.addAll(servers.keySet());
  37.         for (String server : servers.keySet()) {
  38.             int weight = servers.get(server);
  39.             weightMap.put(server, weight);
  40.         }
  41.     }
  42.     @Override
  43.     public String chooseServer() {
  44.         int weightSum = weightMap.values().stream().reduce(Integer::sum).orElse(0);
  45.         int randomWeight = ThreadLocalRandom.current().nextInt(weightSum) + 1;
  46.         for (String server : servers) {
  47.             int weight = weightMap.get(server);
  48.             if (randomWeight <= weight) {
  49.                 return server;
  50.             }
  51.             randomWeight -= weight;
  52.         }
  53.         return null;
  54.     }
  55. }
复制代码
6 最快响应时间 (Least Response Time)

最快响应时间(Least Response Time,LRT)是一种智能动态负载均衡算法,它通过选择当前响应时间最短的服务器来处理新请求,从而优化整体系统性能。
5.png

LRT 算法基于以下核心判断标准:

  • 实时性能监控:持续跟踪每台服务器的历史响应时间
  • 动态路由决策:新请求总是分配给响应最快的可用服务器
  • 自适应学习:根据服务器性能变化自动调整流量分配
示例代码:
  1. import java.util.List;
  2. import java.util.zip.CRC32;
  3. public class SourceIPHashLoadBalancer {
  4.     private final List<String> servers;
  5.    
  6.     public SourceIPHashLoadBalancer(List<String> servers) {
  7.         this.servers = servers;
  8.     }
  9.    
  10.     public String getServer(String clientIP) {
  11.         if (servers.isEmpty()) {
  12.             return null;
  13.         }
  14.         
  15.         // 计算IP的哈希值
  16.         long hash = calculateHash(clientIP);
  17.         
  18.         // 取模确定服务器索引
  19.         int index = (int) (hash % servers.size());
  20.         
  21.         return servers.get(Math.abs(index));
  22.     }
  23.    
  24.     private long calculateHash(String ip) {
  25.         CRC32 crc32 = new CRC32();
  26.         crc32.update(ip.getBytes());
  27.         return crc32.getValue();
  28.     }
  29. }
复制代码
来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册