前言
在开始介绍服务稳定性之前,我们先聊一下SLA。SLA(service-level agreement,即 服务级别协议)也称服务等级协议,经常被用来衡量服务稳定性指标。通常被称作“几个9”,9越多代表服务全年可用时间越长服务也就越可靠,即停机时间越短。通常作为服务提供商与受服务用户之间具体达成承诺的服务指标——质量、可用性,责任。
3个9,即99.9%,全年可停服务时间:365 * 24 * 60 *(1-99.9%)= 525.6min
4个9,即99.99%,全年可停服务时间:365 * 24 * 60 *(1-99.99%)= 52.56min
5个9,即99.999%,全年可停服务时间:365 * 24 * 60 *(1-99.999%)= 5.256min
在严苛的服务级别协议背后,其实是一些列规范要求来进行保障。
一、系统稳定性建设是指什么?
关于系统稳定性是指什么这一问题,相信好多开发同学都会有自己的理解和认知,但可能会存在是否理解片面或者是否标准的疑惑,那到底有什么判定标准和划分边界呢?
我们不妨看下来自于维基百科的解释:
稳定性是数学或工程上的用语,判别一系统在有界的输入是否也产生有界的输出。
若是,称系统为稳定;若否,则称系统为不稳定。
简单理解,系统稳定性本质上是系统的确定性应答。
从另一个角度解释,服务稳定性建设就是如何保障系统能够满足SLA所要求的服务等级协议。
本文重点介绍服务端稳定性需要考虑的关键要素和策略,重点介绍变更之外的稳定性保障。
总结一下,稳定性的时间节点主要包括:
1、事前:消除潜在风险,确保系统稳定运行不出问题。上医治未病,所以这一点要重点投入。
2、事中:监控快速感知和响应的体系,包括风险的感知、控制,并且团队要训练有素才能最快速度消除风险。
3、事后:深度复盘和改进,在系统运行过程中对已发生问题的总结、故障的处理、优化和预防措施的制定。
二、稳定性建设具体动作
1、事前:
我们先看下事前可以做的事情,或者说平时的研发规范、预防的实践:
变更过程中的风险更多来自变更前的设计、代码质量、review、自动化测试等,而不是仅仅依靠灰度、监控和回滚。
研发规范
1、定期业务串讲:定期业务串讲有助于各个业务线之间的业务互相熟悉、减少以后的沟通成本,并且有助于新人快速熟悉业务,对于各个业务的owner也能更加深刻的理解业务。
2、技术方案评审:
1)通过评审,可以确保后端技术方案的质量,避免在项目实施过程中出现问题。这可以帮助团队更好地理解项目的需求,确保技术方案能够满足这些需求。
2)可以帮助团队识别和解决可能的技术风险,降低项目失败的风险。这可以包括技术债务、性能问题、安全问题等。
3)通过评审,可以确保团队的技术方案是有效的,从而提高开发效率。这可以帮助团队更好地利用资源,提高项目的完成速度。
4)评审可以帮助团队成员更好地理解彼此的技术方案,提高团队协作效率,还可以帮助团队成员更好地理解项目的需求。
5)评审可以帮助团队确保后端技术方案的可扩展性,以应对项目的增长和变化。可以充分发挥团队的力量,一起探讨技术选型和可扩展性
3、代码review:Code Review是现代软件开发团队中非常重要的一环,因为它可以带来以下几个方面的好处:
1)提高代码质量: 通过代码审查,开发团队可以及时发现和修复代码中的问题,包括代码中的错误、潜在的安全漏洞、缺陷和性能问题等,从而提高代码的质量。
2)减少维护成本: 通过及时发现和修复问题,代码审查可以降低后续维护成本,因为修复问题的成本通常比在后期修复更低。
3)加强知识共享和团队协作: 代码审查可以帮助团队成员了解项目中其他成员的工作,从而促进知识共享和团队协作,提高团队整体的开发能力。
4)提高编码规范和标准的遵守: 通过代码审查,可以促进团队成员遵守编码规范和标准,统一团队的代码风格和代码质量要求,提高代码可读性和可维护性。
5)促进开发者的技能提升和成长:代码审查可以帮助开发者了解项目中的技术细节和最佳实践,从而促进开发者的技能提升和成长。
切流预案
1、新功能开关:新上线的功能需要添加分布式配置开关,如果有问题,可以及时切换到旧版本。
2、灰度放量预案:灰度按百分比放量是一种软件开发中常用的功能发布方法,它可以帮助提高软件可靠性,提高用户体验,在实施时也需要注意几个方面:
1)确定放量目标:首先需要确定放量的目标,例如增加多少百分比的数据量。这个目标需要根据实际情况进行制定,例如需要考虑数据量的大小、计算资源的限制等因素。
2)确定放量规则:你需要确定在放量过程中,哪些功能会被启用,哪些功能会被禁用。你可以根据开发进度、测试结果和市场需求等因素来确定放量规则。
3)监控放量过程:在实施放量操作时,需要监控放量过程,以确保放量结果的稳定性和可靠性。如果出现异常情况,需要及时采取措施进行调整。
稳定运行
1、机器健康度:磁盘空间、网络抖动、流量不均引起单机风险等。尤其是磁盘空间满,对于成熟团队来说应该是低级事故,不应该出现。应该有完善的平台、机制确保一定不会出现磁盘满。
2、容量规划:计划中的大促等,需要提前规划好容量。在规划前需要准确压测摩的系统性能数据。
3、自愈能力:这是一项高级但也非常必要的能力。可以举一个典型的发面案例:系统异常导致内存中的任务队列大量堆积,异常清除后还在持续消费内存中堆积的任务,必须人工重启来干预。这种情况下,应该设置合理的队列最大长度、丢弃过期的任务、背压等手段来实现自愈,避免依赖人工干预导致故障恢复时间拉长。
4、极限压测:理想的压测应该是常态化进行极限场景压测、每次变更前后进行压测、定期进行线上流量回放压测以及时发现流量特征变化对性能的影响。实际中,因为自动化程度不够高,不能完全做到,但是要持续往这个方向发展。
团队训练有素
以上的风险感知、风险控制手段能否有效执行,取决于团队是否训练有素。平时头脑清醒,重大故障期间慌的不知所措时很容易出现的,即使有预案也想不起来或者不敢执行。
1、应急预案演练:前面讲过,只有反复演练过的故障才敢真的去执行,尤其是有损预案。
2、突袭演练:突袭更接近于真实场景的演练,日常可以团队内互相突袭,也可以找风险团队协助联动做红蓝对抗突袭。
3、故障响应演练:专业的故障响应过程,一定要有多个训练有素的角色高效配合才能最大限度压缩故障时长,要有指挥员负责整体把控、资源协调,通讯员负责信息收集、对组织内和客服甚至公关口径及时传递有效信息,要有专人去执行预案尽快恢复服务,也有要人去分析原因确保元无法消除影响后进一步处理。最典型的不专业表现是故障后所有人都扑上去寻找原因,这是大忌。如果看过足够多集团重大故障的话,应该能够发现我们有不少的故障原因是十几个人数天时间才能真正分析清楚的。故障期间,原因分析之要能满足故障恢复即可,不要强迫自己一定要分析到根本原因。比如服务异常后,定位到是db异常,这个时候如果有提前db降级预案,就可以快速评估是否执行了,而不是分析db异常的根本原因,我们有些db异常最后分析到是mysql内核层的bug,如果要分析到这种级别的根本原因才能恢复服务那对业务来说绝对是灾难。
2、事中:
风险感知
1、监控:监控这部分需要单独做系统性设计,后面单独分享。原因是平时还是经常看到核心系统都有监控,但是监控的覆盖面、问题诊断能力严重不足。做的稍微好点的有调用量、成功率、耗时等监控,做的差的只有几个调用量的监控根本不具备问题感知能力。还可以添加同比环比这类指标,如果指标下降明显,可以触发相应报警。
2、预警:预警首先要覆盖所有故障场景,直接造成故障风险的一定要有电话告警。而且预警要持续优化,降低到大家每条都能处理的程度,过度告警等于没有告警了。
3、反馈:收到预警后要能快速处理,可以值班也可以由指定人跟进。
风险控制
1、容灾切换:如果有同城容灾、异地容灾、单元化、区域化等容灾手段的话,切换到其他可用区是一个可用快速恢复服务的手段。
2、限流:当DB出现大量慢SQL,突发流量造成容量风险时候,限流是避免系统彻底崩溃的有效手段,限流能力必须提前做好建设。
3、降级:降级通常会有一定的牺牲,但是可以确保核心的功能可用,比如牺牲一定体验。一般提前会有预案,在代码和配置中一般提前会有各种情况的降级措施。
4、故障隔离:通常是最后没有办法的时候的手段,比如新设备上线后会在很长一段时间里会有独立的接入点,避免新设备的访问异常造成无线大的访问冲击影响其他存量设备接入。避免故障影响上下游,所有依赖的服务和被依赖的服务
值班机制
1、轮流值班:每天安排指定人员值班,有问题如果自己能解决直接处理,无法解决可联系相关owner,并记录相关问题和进展。
2、服务有主备:每个微服务的owner要有主备负责人,出问题的时候,如果owner有特殊情况无法第一时间处理,可由另一个owner及时解决。
3、问题及时反馈:处理不了的问题,及时将工单转给相应负责人,系统告警要及时ack,并跟进处理。
及时止损
1、及时通知:有问题第一时间发出通知,通知对应的上下游,以及所有可能影响到的业务方。
2、及时降级服务:核心服务如果默认降级措施无法生效,及时降级到紧急预案。
3、及时恢复数据:在技术方案设计阶段其实就已经要有相应的恢复数据的预案,故障发生时,评估相应影响后,及时恢复数据,可将损失降到最小。
4、及时扩容:及时关注系统资源利用率,提前规划好,及时扩容。
5、及时修复:如果是小问题,不适合回滚的项目,可申请bug修复上线;若适合回滚的项目,根据监控的波动曲线,如果对应指标下降明显,及时回滚代码。
3、事后:
复盘
事后的首要任务是对发生的故障进行分析,并定位根本原因。这包括收集故障发生时的日志、性能数据以及相关事件信息。通过深入分析这些数据,可以找到问题的起因,从而避免类似问题再次发生。复盘的目的不是为了惩罚,而是为了以后不犯类似的错误,而且复盘可以发掘系统中类似的缺陷,并及时改进。以下是一些在事后阶段可以采取的策略和措施,以确保系统的持续稳定性。在这个阶段,可以采用以下策略:
1、5why分析法:所谓5why分析法,又称“5问法”,也就是对一个问题点连续以5个“为什么”来自问,以追究其根本原因。虽为5个为什么,但使用时不限定只做“5次为什么的探讨”,主要是必须找到根本原因为止,有时可能只要几次,有时也许要十几次,如古话所言:打破砂锅问到底。5why法的关键所在:鼓励解决问题的人要努力避开主观或自负的假设和逻辑陷阱,从结果着手,沿着因果关系链条,顺藤摸瓜,直至找出原有问题的根本原因。
2、日志分析: 仔细检查系统的日志,包括错误日志、调试日志等,以找出故障的发生时间、位置和可能的原因。
3、性能分析: 利用性能监控工具,分析故障发生时系统的性能指标,找出可能的性能瓶颈。
4、事务追踪: 对系统中关键业务流程进行事务追踪,以确定故障发生时的具体业务场景。
5、定责:根据公司规定和影响范围来定责。
6、定级:复盘后,根据结论对当前故障定级,并发出公告。
性能优化
在故障发生后,对系统的性能进行全面分析,找出瓶颈和问题点,然后制定性能优化策略。这可以通过以下方式实现:
1、性能测试: 针对关键业务场景进行性能测试,找出系统在高负载情况下的性能瓶颈。
2、代码审查: 对系统的核心代码进行审查,寻找潜在的性能问题,并进行必要的重构。
3、数据库优化: 针对数据库的查询性能进行优化,包括索引优化、查询语句优化等。
自动化运维
在事后,可以加强系统的自动化运维,减少人为操作的风险。自动化运维包括:
1、自动化部署: 使用持续集成/持续部署(CI/CD)工具,实现自动化的部署流程,减少部署过程中的人为错误。
2、自动化测试: 扩展自动化测试覆盖范围,包括单元测试、集成测试、端到端测试等,确保每次发布都是可靠的。
3、自动化监控与预警: 将监控和预警的设置与运维流程相结合,实现对系统状态的实时监控和及时响应。
安全审计与漏洞修复
事后还需要对系统进行安全审计,确保系统没有潜在的安全风险。具体措施包括:
1、安全漏洞扫描: 定期使用安全漏洞扫描工具,对系统进行全面扫描,及时发现并修复潜在的安全问题。
2、代码审计: 对系统的代码进行审计,检查是否存在安全漏洞和潜在的风险点。
3、安全培训: 对团队进行定期的安全培训,提高团队成员的安全意识,减少因为人为失误引起的安全问题。
文档与知识库更新
在事后阶段,及时更新系统文档和知识库,记录故障处理的经验教训,为未来遇到类似问题的团队成员提供参考。具体做法包括:
1、故障总结文档: 汇总对于不同类型故障的总结文档,包括根本原因、解决方案和未来预防措施。
2、运维手册更新: 更新系统的运维手册,包括部署流程、故障处理流程等,确保手册的实时性和准确性。
3、知识库建设: 建设团队内部的知识库,汇总团队成员的经验分享和技术教程,方便团队成员学习和查阅。
性能监控和持续优化
引入持续监控系统,实时追踪系统性能和稳定性,确保在生产环境中发现问题时能够及时响应。具体策略包括:
1、监控系统升级: 随着系统规模和复杂性的增加,持续升级监控系统,引入更智能的告警和分析功能。
2、容量规划: 根据系统的使用情况,进行容量规划,提前预测系统的资源需求,避免因为资源不足而导致的性能问题。
3、性能优化迭代: 定期进行性能优化的迭代,不断寻找和解决系统中的性能瓶颈,提高整体性能。
灾难恢复演练
定期进行灾难恢复演练,检验灾备和容灾方案的可用性和有效性。演练可以模拟不同的灾难场景,确保在真正的紧急情况下,团队能够迅速而有效地进行恢复操作。
三、稳定性建设案例学习
美团点评智能支付核心交易系统的可用性实践
https://tech.meituan.com/2018/04/19/trade-high-availability-in-action.html
参考文章:
稳定性建设(一) https://www.jianshu.com/p/68008fb8b025