【八股消消乐】构建微服务架构体系—保证服务高可用
😊你好,我是小航,一个正在变秃、变强的文艺倾年。
🔔本专栏《八股消消乐》旨在记录个人所背的八股文,包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法
等相关知识点,期待与你一同探索、学习、进步,一起卷起来叭!
目录
- 题目
- 答案
- 容错
- 限制故障影响范围
- 快速发现和快速修复故障
- 规范变更流程
- 简历准备
- 发现问题
- 计划方案
- 落地实施
- 取得效果
- 后续改进
题目
💬技术栈:微服务架构
🔍简历内容:通过引入全方位的监控与告警、各种服务治理措施,解决了由于其他业务组功能上线而引起的Redis大对象请求慢,导致核心服务超时问题,最终可用性从99达到了999。
🚩面试问:四个九代表全年不可用时间不超过 53 分钟,那么你知道三个九和五个九又各自代表多少时间吗?从你个人经历出发,你认为四个九的可用性,究竟难不难达成?
💡建议暂停思考10s,你有答案了嘛?如果你有不同题解,欢迎评论区留言、打卡。
答案
一般衡量可用性,我们都是用 SLA(Service Level Aggrement)指标,通常用 N 个九
来说明。例如,当我们说微服务的可用性是三个九,是指系统在一段时间内(一般是一年)正常提供服务的时间超过了 99.9%
。
核心有四点:
- 容错;
- 限制故障影响范围;
- 出现故障可以快速发现,快速修复;
- 规范变更流程。
容错
容错:不管发生了什么,你的系统都能正常提供服务,也就是所谓的 Design for Failure。用一句俗语来说,就是 凑合用。
限制故障影响范围
限制故障影响范围:万一真的出现了故障,也要尽可能减轻它的影响范围。影响范围可以从三个角度来考虑,尽可能使故障造成的业务损失更小、被影响的用户更少,还有被影响的其他组件更少
。
影响范围的因素:
- 服务互相依赖, 这种依赖一部分源自业务本身的复杂度,另外一部分则源自设计不合理。我们可以通过改进设计来
降低服务之间的依赖
,但是不可能做到彻底没有依赖。 - 服务共享一部分基础设施。理论上只要你有足够多的钱,能够为每一个服务提供完全独立的基础设施,就可以彻底解决这个问题。但是实际中大部分公司
连部署两套 Redis 都舍不得
,所以我们经常听到某某公司因为共享基础设施导致系统崩溃的事故。
快速发现和快速修复故障
快速发现强调的是 完备的观测和告警系统。
- 观测不仅要观测服务本身,也要对各种基础设施、第三方依赖进行观测。尤其是在你核心链路上依赖的东西,你都需要进行全方位地观测。
- 有了观测之后,还要设置合理的告警。 没有告警的观测是没有灵魂的。
快速恢复则是尽可能减少服务不可用的时间
。快速修复与其说是一个工程技术问题,不如说是一个组织建设问题。它实际上要求每一个组都需要安排人 24 小时值班,并且每个值班的人都需要了解整个组所维护的项目的细节,否则出了故障都没人响应,或者不知道怎么响应。
可以借助一个独立的系统来处理业务系统发生的故障。
微服务集群自动扩容。它是指对整个微服务集群进行监控,如果发现集群负载过高那么就会自动扩容。
为了进一步提高整个集群服务的可用性,我跟运维团队进行密切合作,让他们支持了自动扩容
。整个设计方案是允许不同的业务方设置不同的扩容条件,满足条件之后运维就会自动扩容
。比如说我为我的服务设置了 CPU 90% 的指标
。如果我这个服务所有节点的 CPU 使用率都已经超过了 90%,并且持续了一段时间
,那么就会触发自动扩容,每次扩容会新增一个节点。
为什么是所有节点的CPU使用率超过了90%。
CPU 使用率长期处于高位,基本上代表节点处于高负载状态。万一某个节点非常不幸,处理的都是复杂的请求,那么它就会处于高负载的状态,但是其他节点其实负载还很低。那么这个时候扩容,并没有什么效果。
其他的示例方案:
- 自动修复数据,最常见的就是
有一个定时任务比对不同的业务数据,如果数据不一致,就会发出告警,同时触发自动修复动作
。 - 自动补发消息,也是
通过定时任务等机制来比对业务数据,如果发现某条消息还没发,就会触发告警,同时触发补发消息动作
。
规范变更流程
规范变更流程是指任何一个人都不能随意发布新版本,也不能随意修改配置。任何一个变更都要经过 review,并且做好回退的准备。
简历准备
整个思路可以拆解成几个部分,分别是 发现问题、计划方案、落地实施、取得效果、后续改进。
发现问题
某某业务是我们公司的核心业务
,它的核心困难是需要保证高可用
。在我刚入职的时候,这个系统的可用性还是比较低
的。比如说我刚入职的第一个月就出了一个比较严重的线上故障
,别的业务组突然上线了一个功能
,带来了非常多的 Redis 大对象操作
,以至于 Redis 响应非常慢,把我们的核心服务搞超时了
。
后面经过调研,我总结下来,系统可用性不高主要是这三个原因导致的。
缺乏监控和告警
,导致我们难以发现问题,难以定位问题,难以解决问题。缺乏服务治理
,导致某一个服务出现故障的时候,整个系统都不可用了。缺乏合理的变更流程
。我们每次复盘 Bug 时候,都觉得如果有更加合理的变更流程的话,那么大部分事故都是可以避免的。
计划方案
针对这些具体的点,我的可用性改进计划分成了几个步骤。
- 引入全方位的监控与告警,这一步是为了快速发现问题和定位问题。
- 引入各种服务治理措施,这一步是为了提高服务本身的可用性,并且降低不同服务相互之间的影响。
- 为所有第三方依赖引入高可用方案,这一步是为了提高第三方依赖的可用性。
- 拆分核心业务与非核心业务的共同依赖。这一步是为了进一步提高核心业务的可用性。
- 规范变更流程,降低因为变更而引入 Bug 的可能性。
落地实施
第一个步骤:就监控来说,既要为业务服务添加监控和告警,又要为第三方依赖增加监控,比如说监控数据库、Redis 和消息队列。而告警则要综合考虑告警频率、告警方式以及告警信息的内容是否足够充足,减少误报和谎报
。本身这个东西并不是很难,就是非常琐碎,要一个个链路捋过去,一个个业务查漏补缺
。
第二个步骤:服务治理包括的范围比较广,我使用过的方案也比较多,比如说限流熔断
等等。
第三个步骤:遇到了比较大的阻力,主要是大部分第三方依赖的高可用方案都需要资金投入
。比如说最开始我们使用的 Redis 就是一个单机 Redis,那么后面我尝试引入 Redis Cluster 的时候,就需要部署更多的实例。
第四个步骤:执行得不彻底。现在的策略就是新的核心业务会启用新的第三方依赖集群,比如说 Redis 集群
,但是老的核心业务就保持不动。
第五个步骤:我在公司站稳脚跟之后跟领导建议过几次,后来领导就制定了新的规范,主要是上线规范,包括上线流程、回滚计划等内容
。
取得效果
经过我的改进之后,现在我维护的服务的可用性从原来不足两个九提升到了三个九
。现在 Bug 数量也减少了。Bug 复盘的时候我已经不再是那个挨骂的人了,变成了看别人挨骂的人
。
为什么三个九也敢说是高可用?
我也一直在想办法进一步提高可用性
,但是整个系统要做到四个九还是非常难的,需要整个公司技术人员一起努力才能达到
。我在公司的影响力还局限在我们部门,困难比较多,暂时做不到那么高的可用性。
后续改进
已有方案的缺点:目前我的服务,尤其是一些老服务,相互之间还是在共享一些基础设施
。一个出问题就很容易牵连其他服务
,所以我还需要进一步将这些老服务解耦。
我一定要让我的全部服务都使用我自己所在组的数据库实例,省得因为别组的同事搞崩了数据库,牵连到我的业务
。大家一起用一个东西,出了事别人死不认账,甩锅都甩不出去。
往期精彩专栏内容,欢迎订阅:
🔗【八股消消乐】20250615:构建微服务架构体系—链路超时控制
🔗【八股消消乐】20250614:构建微服务架构体系—实现制作库与线上库分离
🔗【八股消消乐】20250612:构建微服务架构体系—限流算法优化
🔗【八股消消乐】20250611:构建微服务架构体系—降级策略全总结
🔗【八股消消乐】20250610:构建微服务架构体系—熔断恢复抖动优化
🔗【八股消消乐】20250609:构建微服务架构体系—负载均衡算法如何优化
🔗【八股消消乐】20250608:构建微服务架构体系—服务注册与发现
🔗【八股消消乐】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.15
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!