思考:如何保证服务稳定性?
转载:https://zhuanlan.zhihu.com/p/150377297?from_voters_page=true
最近一直在忙618大促的全链路压测&稳定性保障相关工作,结果618还未开始,生产环境就出了几次生产故障,且大多都是和系统稳定性、性能相关的bad case。生产全链路压测终于告一段落,抽出时间将个人收集的稳定性相关资料整理review了一遍,顺带从不同的维度,谈谈稳定性相关的“务虚”认知和思考。。。
一、SLA!
在开始谈稳定性保障之前,我们先来聊聊业内经常提及的一个Topic:SLA!
业内喜欢用SLA (服务等级协议,全称:service level agreement)来衡量系统的稳定性,对互联网公司来说就是网站服务可用性的一个保证。9越多代表全年服务可用时间越长服务越可靠,停机时间越短。就以一个标准99.99%为例,停机时间52.6分钟,平均到每周也就是只能有差不多1分钟的停机时间,也就是说网络抖动这个时间可能就没了。保证一个系统四个9或者更高的五个9,需要一套全体共识严格标准的规章制度,没有规矩不成方圆。创建的规范有如下几种:
1、研发规范、自身稳定;
2、事务中不能包含远程调用;
3、超时时间和重试次数要合理;
4、表数据操作必须double check,合理利用索引,避免出现慢查询、分库分表不走分表键;
5、没有有效的资源隔离, 避免不同业务共用一个线程池或连接池;
6、合理的系统拓扑,禁止不合理服务依赖,能依赖就依赖,否则同步尽量改成异步弱依赖;
7、精简的代码逻辑;
8、核心路径流程必须进行资源隔离,确保任何突发情况主流程不能受影响。
二、单服务稳定性
关键字:开关可控、单一职责、服务隔离、异常兜底、监控发现!
对于稳定性来说,抛开整体系统架构设计,单就每个业务域服务的稳定性也是非常的重要。只有每个业务环节都稳如泰山,才能保障整个稳定性。单服务稳定可以从以下几个方面来进行:
1、禁用设计:应该提供控制具体功能是否开启可用的配置,在相应的功能服务出现故障时,快速下线局部功能,以保证整体服务的可用性;
2、必要的缓存:缓存是解决并发的利器,可以有效的提高系统的吞吐量。按照业务以及技术的纬度必要时可以增加多级缓存来保证其命中率;
3、接口无状态性:服务接口应是无状态的,当前接口访问不应该依赖上层接口的状态逻辑;
4、接口单一职责性:对于核心功能的接口,不应该过多的耦合不属于它的功能。如果一个接口做的事情太多应做拆分,保证单接口的稳定性和快速响应;
5、第三方服务隔离性:任何依赖于第三方的服务(不论接口还是中间件等),都应该做到熔断和降级,不能有强耦合的依赖;
6、业务场景兜底方案:核心业务场景要做到完整兜底方法,从前端到后端都应有兜底措施;
7、服务监控与及时响应:每个服务应做好对应监控工作,如有异常应及时响应,不应累积。
三、集群稳定性
关键字:系统架构、部署发布、限流熔断、监控体系、压测机制!
对于集群维度的稳定性来说,稳定性保障会更加复杂。单服务是局部,集群是全局。一个见微知著,一个高瞻远瞩。
1、合理的系统架构:合理的系统架构是稳定的基石;
2、小心的代码逻辑:代码时刻都要小心,多担心一点这里会不会有性能问题,那里会不会出现并发,代码就不会有多少问题;
3、优秀的集群部署:一台机器永远会有性能瓶颈,优秀的集群部署,可以将一台机器的稳定放大无限倍,是高并发与大流量的保障;
4、科学的限流熔断:高并发来临时,科学的限流和熔断是系统稳定的必要条件;
5、精细的监控体系:没有监控体系,你永远不会知道你的系统到底有多少隐藏的问题和坑,也很难知道瓶颈在哪里;
6、强悍的压测机制:压测是高并发稳定性的试金石,能提前预知高并发来临时,系统应该出现的模样;
7、胆小的开发人员:永远需要一群胆小的程序员,他们讨厌bug,害怕error,不放过每一个波动,不信任所有的依赖。
四、稳定性专项
专项指的是针对某些特定场景下的特定问题而梳理出对应的方案。下面是针对一些常见的稳定性专项的概述:
1、预案:分为定时预案和紧急预案,定时预案是大促常规操作对于一系列开关的编排,紧急预案是应对突发情况的特殊处理,都依赖于事前梳理;
2、预热:分为JIT代码预热和数据预热,阿里内部有专门的一个产品负责这块,通过存储线上的常态化流量或者热点流量进行回放来提前预热, 起源于某年双十一零点的毛刺问题,原因是访问了数据库的冷数据rt增高导致的一系列上层限流,现在预热已经成了大促之前的一个必要流程。
3、强弱依赖:梳理强弱依赖是一个偏人肉的过程,但是非常重要,这是一个系统自查识别潜在风险点并为后续整理开关限流预案和根因分析的一个重要参考,阿里内部有一个强弱依赖检测的平台,通过对测试用例注入RPC调用的延迟或异常来观察链路的依赖变化,自动梳理出强弱依赖关系。
4、限流降级熔断:应对突发流量防止请求超出自身处理能力系统被击垮的必要手段;
5、监控告警&链路追踪:监控分为业务监控、系统监控和中间件监控和基础监控,作为线上问题发现和排查工具,重要性不言而喻。
五、稳定性建设
稳定性建设,就和基础技术建设一样,是一个长期迭代和不断调整的过程,业内常见的稳定性建设类型,主要有如下几种:
1、容量规划:个人感觉容量规划在大厂里也并没有做的很好,更多依赖的是业务方自己拍脑袋,然后全链路压测期间验证,不够就再加机器。
2、混沌工程:混沌工程是近几年比较火的名词,通过不断给系统找麻烦来验证并完善系统能力,阿里在这块花了很大的精力建设红蓝军对抗攻防,进行定期和不定期的演练,最后以打分的形式来给各个部门系统做排名,除了系统层面的故障演练外还有资金演练,篡改线上sql语句制造资损来测试业务监控纠错的能力,通过制造小错来避免大错。
跳转门:混沌工程-初识
3、流量调度:通过metric秒级监控和聚类算法实时找出异常单机来降低RPC流量权重,提升集群整体吞吐能力减少异常请求。
4、容灾&异地多活:起源于15年某施工队将光纤挖断带来的支付宝故障,由此出来的三地五中心和单元化架构,异地多活本身的成本比较高,然后又存在数据同步的延时问题和切流带来的脏数据问题,对于业务和技术都有比较高的要求。常见的容灾有如下几种:
1)缓存挂掉,集群重启缓存预热如何处理?本地缓存,多级缓存是否可以替代?
2)分布式锁,是否有开关一键切换?比如:ZK/ETCD编写的分布式锁;
3)大促峰值流量,如何防止外部ddos攻击?如何识别流量类型?
4)资源隔离:资源隔离,服务分组,流量隔离;
5)高可用思想:避免单点设计!
6)容错:容错上游,防御下游。容错主要需要注意如下几点:
6-1:外部依赖的地方都要做熔断,避免雪崩;
6-2:对于依赖我们的上游要限流,防止上游突发超过自己系统能够扛住的最大QPS;
6-3:对于下游既要评估好接口超时时间,防止下游接口超时导致自己系统被拖累;
6-4:下游接口要考虑各种异常情况,需要考虑中间状态,通过引入柔性事务,确保数
据最终一致。
5、异地多活
异地多活的本质,是数据中心架构的演进。
1)演进:单机房——双机房——异地灾备——异地多活;
2)定义:分多个地域、多个数据中心运行线上的业务,并且每个IDC均提供在线服务;
3)优点:弹性扩展能力、流量就近接入、灵活调度、提升可用性与用户体验、容灾;
4)步骤:
4-1:基础设施:机房之间专线互联,保证网络质量稳定;
4-2:持久存储:一主三从,主IDC同步复制,异地IDC异步复制;
4-3:中间件:DB、MQ、分布式存储;
4-4:应用部署:根据应用域划分,不同应用部署在不同地域,保持亲缘性;
4-5:流量接入与调度:网络协议兼容,DNS,动态调度用户就近访问;
4-6:监控与运维保障:专线实时监控,确保发生故障时可以触发Failover(失效备援)和
流量调度。
六、稳定性思考
关键字:阶段工作、角色转变!
稳定性建设是一个演进的阶段性过程,主要分为三个阶段:
1、发现问题解决问题:当问题较多时候就很被动,很多时候我们通过不断完善监控来确保我们来快速定位问题,但仍处于被动的一方;
2、主动寻找问题:混沌工程、破坏性测试、极限压测、红蓝对抗等手段,一方作为创造问题方不断挑战系统极限,另一方见招拆招快速修复。
3、角色转变:这个过程中会积累很多处理问题的经验,不断完善系统健壮性,争取在用户发现问题前消灭于萌芽中。角色转变,变被动为主动。