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

一、注册中心是什么?
注册中心是RPC框架的“通讯录”:
- 服务端(提供者):启动时把自己的地址、接口信息注册进去
- 客户端(消费者):调用时从注册中心发现可用服务节点
- 心跳/监听:保证节点健康,自动剔除故障节点
二、核心功能
- 服务注册:服务启动时把节点信息存入注册中心
- 服务发现:客户端获取可用服务节点列表
- 心跳续约:防止节点因故障假死
- 服务下线:服务停机主动/自动删除节点
- 监听机制:节点变化实时通知客户端
- 本地缓存:提升性能,减轻注册中心压力
- 多注册中心支持:Etcd / ZooKeeper 可插拔
三、整体结构设计
1. 统一接口(规范)
▼java复制代码public interface Registry { void init(RegistryConfig config); // 初始化 void register(ServiceMetaInfo info); // 注册 void unRegister(ServiceMetaInfo info); // 注销 List<ServiceMetaInfo> serviceDiscovery(String serviceKey); // 发现 void destroy(); // 销毁 void heartBeat(); // 心跳 void watch(String key); // 监听 }
2. 工厂 + SPI 可扩展
▼java复制代码public class RegistryFactory { static { SpiLoader.load(Registry.class); } public static Registry getRegistry(String key) { return SpiLoader.getInstance(Registry.class, key); } }
支持 Etcd、ZooKeeper、Nacos 无缝切换。
3. 本地注册(内存存储)
▼java复制代码public class LocalRegistry { private static final Map<String, Class<?>> SERVICE_MAP = new ConcurrentHashMap<>(); }
作用:服务端反射调用时快速找到实现类。
四、Etcd 注册中心实现
1. 核心机制
- Key-Value 存储
- 租约(Lease):节点30秒过期
- 心跳续约:每10秒续期一次
- Watch 监听:节点删除自动清空缓存
2. 存储结构
▼text复制代码/rpc/服务名:版本号/地址:端口 -> {服务元信息}
示例:
▼text复制代码/rpc/com.xxx.UserService:1.0/127.0.0.1:8080
3. 服务注册流程
- 申请 30s租约
- 拼接 key、存储 value
- 绑定租约存入 Etcd
- 加入本地缓存
- 启动心跳定时任务
4. 心跳实现(最关键)
▼java复制代码// 每10秒执行一次 CronUtil.schedule("*/10 * * * * *", task -> { for (String key : localRegisterNodeKeySet) { // 获取租约ID long leaseId = kvs.get(0).getLease(); // 手动续约 leaseClient.keepAliveOnce(leaseId); } });
5. 服务发现流程
- 先查本地缓存
- 缓存不存在 → Etcd前缀查询
- 解析结果 → 写入本地缓存
- 对每个节点 开启监听
6. 监听机制
监听节点删除事件:
▼java复制代码watchClient.watch(key, response -> { for (WatchEvent event : response.getEvents()) { if (event.getEventType() == DELETE) { // 清空缓存,下次强制拉新 registryServiceCache.clearCache(); } } });
五、ZooKeeper 注册中心实现
1. 核心机制
- 临时节点:会话断开自动删除
- 天然心跳:无需手动续约
- Cache 监听:节点变化自动感知
2. 为什么不用心跳?
因为 ZooKeeper 临时节点特性:
- 客户端断开 → 节点自动删除
- 无需代码实现心跳
3. 服务注册
▼java复制代码serviceDiscovery.registerService(instance);
4. 服务监听
▼java复制代码CuratorCache cache = CuratorCache.build(client, key); cache.listenable().addListener( CuratorCacheListener.builder() .forDeletes(child -> clearCache()) .build() );
六、服务本地缓存(RegistryServiceCache)
▼java复制代码public class RegistryServiceCache { List<ServiceMetaInfo> serviceCache; void writeCache(); List<ServiceMetaInfo> readCache(); void clearCache(); }
作用:
- 避免频繁请求注册中心
- 提高调用速度
- 注册中心宕机仍可使用缓存调用
七、服务启动初始化(ProviderBootstrap)
▼java复制代码public class ProviderBootstrap { public static void init(List<ServiceRegisterInfo<?>> list) { // 1. RPC 初始化 RpcApplication.init(); // 2. 本地注册 LocalRegistry.register(serviceName, implClass); // 3. 注册中心注册 Registry registry = RegistryFactory.getRegistry(type); registry.register(serviceMetaInfo); // 4. 启动 TCP 服务 VertxTcpServer server = new VertxTcpServer(); server.doStart(port); } }
八、客户端调用流程(ServiceProxy)
▼java复制代码// 1. 从注册中心发现服务 List<ServiceMetaInfo> list = registry.serviceDiscovery(serviceKey); // 2. 负载均衡选择一个节点 ServiceMetaInfo selected = loadBalancer.select(params, list); // 3. 发送 TCP 请求 RpcResponse response = VertxTcpClient.doRequest(request, info);
九、总结
- 接口化设计:可随意切换注册中心实现
- SPI 加载:高度可扩展
- Etcd 租约+心跳:保证节点健康
- ZooKeeper 临时节点:天然健康检查
- 本地缓存:高性能
- Watch 监听:实时感知节点上下线
- 优雅停机:服务下线主动删除节点
- 统一存储结构:服务名+版本+地址
十、不同注册中心对比
| 特性 | Etcd | ZooKeeper |
|---|---|---|
| 存储类型 | KV | 树结构 |
| 节点类型 | 带租约 | 临时/持久 |
| 心跳 | 代码实现 | 无需实现 |
| 监听 | Watch | Cache |
| 一致性 | Raft | ZAB |
| 易用性 | 高 | 中 |
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
Day 103✅ 今天做了:复习了多用户通信系统⏰ 明天计划:学习Java反射
1
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
