【八股消消乐】构建微服务架构体系—服务注册与发现
😊你好,我是小航,一个正在变秃、变强的文艺倾年。
🔔本专栏《八股消消乐》旨在记录个人所背的八股文,包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法
等相关知识点,期待与你一同探索、学习、进步,一起卷起来叭!
目录
- 题目
- 答案
- 服务注册发现模型
- 模板总结
题目
💬技术栈:微服务架构
🔍简历内容:熟悉服务注册与发现模型,了解主流的服务注册中心,如Etcd、Nacos、Eureka、ZooKeeper,熟悉分布式CAP理论,有应对服务注册中心宕机处理经验。
🚩面试问:我司使用etcd作为注册中心,etcd维护团队已离职,如果注册中心宕机了,你的系统会怎么样?如何处理?
💡建议暂停思考10s,你有答案了嘛?如果你有不同题解,欢迎评论区留言、打卡。
答案
手段总结:
(1)启动备份注册中心,而且是异构的备份中心。考虑能做到自动切换吗?还是依赖于人手动切换?
(2)兜底节点:人手动配置一些固定 IP,万一注册中心崩了就用这个。这个缺陷就是 IP 需要人来维护,比如说万一某个IP 不可用了。
具体流程:
1、禁止所有部署(我们使用aws,部署可能会换新机器)【防止故障扩散,etcd集群在节点异常时若继续扩缩容,可能导致数据不一致或脑裂问题。】
2、保护住所有的现有机器,禁止scale in和scale out【多花了很多钱】
3、在经历多轮抢修依然无法启动etcd的情况下,我们切换到了consul【etcd基于Raft协议强一致性模型,故障恢复需严格满足多数节点存活条件】
4、注册中心团队对consul添加了fallback的方案,当consul挂掉的时候进行fallback
5、我们有个服务是通过注册中心获取有序的节点列表从而分配定时任务执行
,注册中心故障时可能有时成功有时失败,所以我们添加了基于配置的固定列表,当注册中心down掉时,我们可以配置自己的机器列表,在内存中做排序,以分配定时任务。【兜底策略】
服务注册发现模型
(1)为什么需要服务注册发现?
你的服务部署在不同的机房、不同的机器上,监听不同的端口。现在你的客户端收到了一个请求,要发送给服务端,那么你的客户端怎么知道哪些服务端能够处理这个请求呢?
所以,一定要注册才能知道哇!
服务注册发现模型如下:
(1)服务上线:
- 服务端启动的时候,需要往注册中心里注册自身的信息,主要是定位信息。
- 注册成功之后,注册中心和服务端要保持心跳。
- 客户端第一次发起对某个服务的调用之前,要先找注册中心获得所有可用服务节点列表,随后客户端会在本地缓存每个服务对应的可用节点列表。
- 客户端和注册中心要保持心跳和数据同步,后续服务端有任何变动,注册中心都会通知客户端,客户端会更新本地的可用节点列表。
- 客户端发送请求。
- 服务端返回响应。
(2)服务下线:
- 服务端通知注册中心自己准备下线了。
- 注册中心通知客户端某个服务端下线了。
- 客户端收到通知之后,新来的请求就不会再给该服务端发过去。
- 服务端等待一段时间之后,暂停服务并下线。
常见的注册中心:ZooKeeper、Nacos、 etcd(为什么要选用该中间件作为注册中心?)
需要搞懂的数据和信息:注册中心的集群规模、读写 QPS(每秒查询率)、机器性能,如 CPU 和内存大小、注册中心出故障之后你排查和后续优化的案例。
模板总结
“你知道服务注册与发现吗?”或者“你知道注册中心吗?”
(1)回答服务注册与发现的基本模型,例如服务上线和服务下线这两个流程的具体步骤
(2)描述所在公司的注册中心
- CAP:注册中心更加关注
CAP 中选 CP 还是选 AP 的问题
。- 解释
- C:Consistency,数据一致性
- A:Availability,服务可用性
- P:Partition-tolerance,分区容错性
- AP:
客户端容错
,例如Eureka、Nacos。客户端就可能拿到错误的可用节点列表
。如果客户端将请求发到错误的可用节点上,就会出现错误,此时客户端自然可以执行容错,换一个可用节点重试。 - CP:
体量小
,集群规模也不大,例如ZooKeeper。
- 解释
- 中间件成熟度
- 社区活跃度
- 性能
(3)注册数据。
服务端注册的数据
除了定位信息是必需的以外
,剩下需要什么数据都是根据微服务框架本身的功能和业务来设计的
。比如说很多微服务框架支持分组功能,那么就可以让服务端在注册的时候同时注册自己的分组信息,比如说当前节点是 VIP 节点。那么客户端在收到 VIP 请求之后就会把请求发给 VIP 节点。【分组
】
(4)高可用。
- 注册服务端崩溃检测:“心跳”
- 注册中心在和服务端进行心跳的时候失败了,就要 立刻通知客户端 该服务端已经不可用了,那么客户端就不会再发请求过来。
- 注册中心还要继续往服务端发心跳。如果只是偶发性的心跳失败,那么注册中心后面心跳是肯定能够连上的,这时候注册中心再通知客户端这个服务端是可用的。【比如说因为网络偶尔不稳定造成的
- 如何重试:考虑
重试次数和重试间隔
。- 比较好的策略是
立刻重试几次
,如果都失败了就再间隔一段时间继续重试
。 - 一定要考虑重试间隔:第一次心跳失败之后,你立刻重试多半也是失败的,因为此时网络很可能还是不稳定。
- 比较好的策略是
- 注册中心在和服务端进行心跳的时候失败了,就要 立刻通知客户端 该服务端已经不可用了,那么客户端就不会再发请求过来。
- 客户端容错:尽量在注册中心或者服务端节点出现问题的时候,依旧保证请求能够发送到正确的服务端节点上。
- 原因:从服务端崩溃到客户端最终知道是有一段延时的。在这段延时内,客户端还是会把请求发送到已经崩溃的服务端节点上。
- 解决方案:“换节点”(failover)
- 延时计算:服务端和注册中心心跳间隔 + 注册中心通知客户端的时间(很快,毫秒级以内)。
- 什么时候再将这个节点挪回可用列表:注册中心发现服务端再次恢复了,那么注册中心会通知客户端,此时客户端更新可用节点列表。
往期精彩专栏内容,欢迎订阅:
🔗【八股消消乐】20250607:MySQL存储引擎InnoDB知识点汇总
🔗【八股消消乐】20250606:MySQL参数优化大汇总
🔗【八股消消乐】20250605:端午节产生的消费数据,如何分表分库?
🔗【八股消消乐】20250604:如何解决SQL线上死锁事故
🔗【八股消消乐】20250603:索引失效与优化方法总结
🔗【八股消消乐】20250512:慢SQL优化手段总结
🔗【八股消消乐】20250511:项目中如何排查内存持续上升问题
🔗【八股消消乐】20250510:项目中如何优化JVM内存分配?
🔗【八股消消乐】20250509:你在项目中如何优化垃圾回收机制?
🔗【八股消消乐】20250508:Java编译优化技术在项目中的应用
🔗【八股消消乐】20250507:你了解JVM内存模型吗?
🔗【八股消消乐】20250506:你是如何设置线程池大小?
🔗【八股消消乐】20250430:十分钟带背Duubo中大厂经典面试题
🔗【八股消消乐】20250429:你是如何在项目场景中选取最优并发容器?
🔗【八股消消乐】20250428:你是项目中如何优化多线程上下文切换?
🔗【八股消消乐】20250427:发送请求有遇到服务不可用吗?如何解决?
📌 [ 笔者 ] 文艺倾年
📃 [ 更新 ] 2025.6.7
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!