负载均衡是 RPC 框架中的核心组件,负责将请求分发到多个服务实例,提高系统性能和可用性:
常见负载均衡算法:
1. 随机算法(Random)
- 原理:随机选择一个服务实例
- 加权随机:根据实例权重设置选择概率
- 优点:实现简单,请求分布均匀
- 缺点:不考虑实例当前负载
- 适用场景:实例性能相近的场景
- 实现示例:
java
public class RandomLoadBalancer { private List<ServiceInstance> instances; private Random random = new Random(); public ServiceInstance select() { int index = random.nextInt(instances.size()); return instances.get(index); } }
2. 轮询算法(Round Robin)
- 原理:按顺序依次选择服务实例
- 加权轮询:根据权重分配请求比例
- 优点:请求分布均匀,实现简单
- 缺点:不考虑实例响应时间差异
- 适用场景:实例性能相近的场景
- 实现示例:
java
public class RoundRobinLoadBalancer { private List<ServiceInstance> instances; private AtomicInteger index = new AtomicInteger(0); public ServiceInstance select() { int idx = index.getAndIncrement() % instances.size(); return instances.get(idx); } }
3. 最少连接算法(Least Connections)
- 原理:选择当前连接数最少的实例
- 优点:考虑实例当前负载,动态分配
- 缺点:需要维护连接数统计
- 适用场景:请求处理时间差异较大的场景
- 实现示例:
java
public class LeastConnectionsLoadBalancer { private List<ServiceInstance> instances; public ServiceInstance select() { return instances.stream() .min(Comparator.comparingInt(ServiceInstance::getActiveConnections)) .orElse(null); } }
4. 一致性哈希算法(Consistent Hash)
- 原理:将请求和服务实例映射到哈希环上
- 优点:
- 相同请求总是路由到同一实例
- 实例增减时影响范围小
- 支持会话保持
- 缺点:实现复杂,可能分布不均
- 适用场景:需要会话保持或缓存一致的场景
- 实现示例:
java
public class ConsistentHashLoadBalancer { private TreeMap<Integer, ServiceInstance> ring = new TreeMap<>(); public void addInstance(ServiceInstance instance) { for (int i = 0; i < 100; i++) { int hash = hash(instance.getAddress() + "#" + i); ring.put(hash, instance); } } public ServiceInstance select(String key) { int hash = hash(key); Map.Entry<Integer, ServiceInstance> entry = ring.ceilingEntry(hash); if (entry == null) { entry = ring.firstEntry(); } return entry.getValue(); } }
5. 最小响应时间算法(Least Response Time)
- 原理:选择平均响应时间最短的实例
- 优点:动态适应实例性能变化
- 缺点:需要维护响应时间统计
- 适用场景:实例性能差异较大的场景
6. IP 哈希算法(IP Hash)
- 原理:根据客户端 IP 进行哈希
- 优点:相同客户端总是访问同一实例
- 缺点:可能导致负载不均
- 适用场景:需要会话保持的场景
7. 加权算法(Weighted)
- 原理:根据实例权重分配请求
- 加权随机:按权重随机选择
- 加权轮询:按权重比例轮询
- 优点:可以根据实例性能分配不同权重
- 适用场景:实例性能差异较大的场景
Dubbo 负载均衡配置:
xml<dubbo:reference interface="com.example.UserService" loadbalance="random"/> <!-- 可选值:random, roundrobin, leastactive, consistenthash -->
gRPC 负载均衡:
- 客户端负载均衡:客户端维护服务列表并选择实例
- 服务端负载均衡:通过代理(如 Envoy)进行负载均衡
- 支持策略:轮询、随机、最少连接等
Nginx 负载均衡配置:
nginxupstream backend { # 轮询 server 192.168.1.1:8080; server 192.168.1.2:8080; # 加权轮询 server 192.168.1.1:8080 weight=3; server 192.168.1.2:8080 weight=1; # IP 哈希 ip_hash; # 最少连接 least_conn; }
选择建议:
- 实例性能相近:随机、轮询
- 需要会话保持:一致性哈希、IP 哈希
- 实例性能差异大:加权算法、最少连接、最小响应时间
- 缓存一致性要求高:一致性哈希
- 简单场景:随机、轮询
注意事项:
- 结合健康检查剔除故障实例
- 定期更新服务实例列表
- 监控负载均衡效果
- 根据实际情况调整算法参数