myrpc 学习笔记-007 负载均衡
项目地址 欢迎访问
笔记总览 myrpc 学习笔记-001 实现简易版 rpc myrpc 学习笔记-002 配置加载 myrpc 学习笔记-003 Mock 服务代理 myrpc 学习笔记-004 序列化实现和 SPI 机制 myrpc 学习笔记-005 注册中心 myrpc 学习笔记-006 自定义协议 myrpc 学习笔记-007 负载均衡 myrpc 学习笔记-008 重试机制 myrpc 学习笔记-009 容错机制 myrpc 学习笔记-0010 启动机制和注解驱动
架构图v7.0.0
- 实现负载均衡
- 支持 轮询 随机 等负载均衡策略
- 支持自定义策略

(1)轮询策略
RoundRobinLoadBalancer
原理:按顺序依次分配请求,使用原子类 AtomicInteger保证多线程安全。
▼java复制代码@Slf4j public class RoundRobinLoadBalancer implements LoadBalancer { // 原子计数器,保证线程安全 private final AtomicInteger currentIndex = new AtomicInteger(0); @Override public ServiceMetaInfo select(Map<String, Object> requestParams, List<ServiceMetaInfo> serviceMetaInfoList) { log.info("当前负载均衡策略: 轮询"); if (serviceMetaInfoList.isEmpty()) return null; int size = serviceMetaInfoList.size(); if (size == 1) return serviceMetaInfoList.get(0); // 取模轮询:计数器自增后对服务数量取模 int index = currentIndex.getAndIncrement() % size; return serviceMetaInfoList.get(index); } }
(2)随机策略
RandomLoadBalancer
原理:使用随机数生成器,从服务列表中随机选择一个节点。
▼java复制代码@Slf4j public class RandomLoadBalancer implements LoadBalancer { private final Random random = new Random(); @Override public ServiceMetaInfo select(Map<String, Object> requestParams, List<ServiceMetaInfo> serviceMetaInfoList) { log.info("当前负载均衡策略: 随机"); int size = serviceMetaInfoList.size(); if (size == 0) return null; if (size == 1) return serviceMetaInfoList.get(0); // 随机生成下标 return serviceMetaInfoList.get(random.nextInt(size)); } }
(3)一致性哈希策略
ConsistentHashLoadBalancer
原理:
- 构建虚拟节点环,解决数据倾斜问题
- 使用
TreeMap模拟哈希环,ceilingEntry寻找匹配节点 - 同一个请求参数始终命中同一个服务节点,适合有状态服务
▼java复制代码@Slf4j public class ConsistentHashLoadBalancer implements LoadBalancer { // 一致性Hash环,TreeMap天然有序 private final TreeMap<Integer, ServiceMetaInfo> virtualNodes = new TreeMap<>(); // 虚拟节点数量(提高分布均匀性) private static final int VIRTUAL_NODE_NUM = 100; @Override public ServiceMetaInfo select(Map<String, Object> requestParams, List<ServiceMetaInfo> serviceMetaInfoList) { log.info("当前负载均衡策略: 一致性哈希"); if (serviceMetaInfoList.isEmpty()) return null; // 1. 构建虚拟节点环 for (ServiceMetaInfo serviceMetaInfo : serviceMetaInfoList) { // 为每个真实节点创建100个虚拟节点 for (int i = 0; i < VIRTUAL_NODE_NUM; i++) { int hash = getHash(serviceMetaInfo.getServiceAddress() + "#" + i); virtualNodes.put(hash, serviceMetaInfo); } } // 2. 计算请求参数的哈希值 int hash = getHash(requestParams); // 3. 寻找大于等于当前hash的最近节点 Map.Entry<Integer, ServiceMetaInfo> entry = virtualNodes.ceilingEntry(hash); // 无匹配节点,返回环的第一个节点 if (entry == null) entry = virtualNodes.firstEntry(); return entry.getValue(); } // 哈希算法(可替换为FNV、MurmurHash等) private int getHash(Object key) { return key.hashCode(); } }
使用方式
- 配置指定策略
▼yaml复制代码rpc: loadBalancer: consistentHash
- 代码中调用
▼java复制代码// 获取负载均衡实例 LoadBalancer loadBalancer = LoadBalancerFactory.getLoadBalancer(rpcConfig.getLoadBalancer()); // 选择服务节点 ServiceMetaInfo selectedService = loadBalancer.select(requestParams, serviceMetaInfoList);
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
Day 29✅ 今天做了:Redis消息队列⏰ 明天计划:继续学消息队列
2
Day 17🧭行动:学习了Python最后一个知识点:异常处理🤓体会:Python 程序一旦发生异常,如果没有捕获处理,程序就会直接崩溃终止。使用"try-except"捕获异常,可以预先写好异常处理方案:比如打印友好提示、记录日志、释放资源,保证程序不会直接退出,还能继续运行。🧑💻代码:try:print("================================")# pri
2
Day1今天学习了java中if的使用
2
day 61今天来学校上课了,和教授谈了,可以接下RA工作,不过一周只能charge 10h, 工资很少,不过一个月600刀也勉强比没有好。今天的工作还没做完,最近在做知识库构造,Ui/UX上周就设计完,现在在做底座的建设今天也让Claude直接帮我把Neetcode150 题目+解题思路+代码给我整理了,我发现我真的只有找碎片化时间才能做题,我还不如先背先回忆(之前都做过)祝祖国母亲节日快乐,也
2
Day 1✅ 今天做了:⏰ 明天计划:📚 今日感悟:
0
