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 68时间19:00~ 22:00(3h)✅ 今天做了:Component注解、Mybatis配置、使用⏰ 明天计划:Lombok、Mapper映射、动态SQL📚 今日感悟:自动配置类DataSourceAutoConfiguration ,会读取properties文件,通过注解:@EnableConfigurationProperties(DataSourceProperties.cl
2
Day 19✅ 今天做了:MCP⏰ 明天计划:AI智能体构建📚 今日感悟:今天MCP问题有点多有点杂,明天找时间再捋一下。继续加油
1
Day 25✅ 今天做了:1、扇贝英语单词打卡2、英语听说读写、听力练习3、微信阅读15分钟4、编程导航学习⏰ 明天计划:待定📚 今日感悟:Keep going!
2
Day 104✅ 今天做了:学习了Java反射及快速入门⏰ 明天计划:继续学习Java反射
1
为啥codex老是提示这个啊
2
