供稿:美图高级技术专家唐扬
整理:三十
硬件的故障、黑天鹅的事件、流量峰值、资源故障、DDOS攻击、程序代码的BUG这些都会影响系统的稳定性。这么多原因都可能导致系统的不稳定,那该如何解决呢?
总的来说分为4个方面,一是做好事前预防,二是故障的及时发现,三是做故障的高效排查,四就是快速恢复。说故障的事前预防前先跟大家分享一个小故事。
春秋时期的名医扁鹊大家应该都知道,他们一家3兄弟都是大夫,扁鹊排行老三,一次魏文王问他:“你们三兄弟谁的医术最高超呢?”扁鹊回答道:“我家大哥的医术最高,二哥其次,我的医术最差。”魏文王不解问道:“不是你的医术最高超么,这早已声名远播。”扁鹊解释“大哥常在病人发病之前就能提前发现并预防,二哥则能在病人出现小病的时候就用药防止恶化,所以大家觉得他们只会医治小毛病医术不高,其实不然。 而我的病人一般都是已经生了大病,我需要开膛破肚为他们进行手术才能治好,正是因为如此大家觉得我医术最好。但其实能预防疾病才是医者最高超的医术。”
由此可见故障的事前预防有多重要,本身对于技术团队的考验也更大,那究竟该怎么做呢?
设计阶段首先要做的就是在进行设计的时候尽量地简化系统的设计,复杂的分布式架构没有足够的精力去维护它,最后只会问题频出,所以从稳定性出发,1个简单的可用的适合产品现状的系统架构才是最好的。
第二我们需要尽量多的了解全局的情况和系统指标,作为系统的研发人员只有了解系统的整体情况才能在出现问题时更好地应对。第三就是为系统选择合适的组件,组件本身的易用性、性能,组件社区的成熟度,使用的维护成本等都是需要考虑的因素。从项目角度出发,一般初期的项目更习惯于用比较激进技术,但是当项目到达中后期,为了保证系统的稳定性,会更倾向于使用更成熟的技术与组件,这样后续的维护也会更加简单。
此外还需要规范设计的评审,尤其在做大设计的时候,存储架构、存储数据、缓存、数据库的设计都要形成文档,把想到的问题提前提出,避免在日后开发过程中出现问题返工。
部署阶段
变更是这个阶段带来系统故障的主要原因,谷歌团队在之前发布的文章里提到说大概70%的故障是来源于变更,但实际上可能90%以上的故障都是由于变更引起的。要避免变更带来的影响,首先要做的就是规范上线的流程,包括上线的时间、 上线的频率、上线的周期等。像美图现在就是规定只有周一和周四每天可以上线1次,周五和节假日之前是严禁上线的,上线的时间也有规范,不能在晚上高峰期的时候也就是在5:30之后禁止上线,另外上线之后,我们会进行监控和观察,尽早发现上线过程中出现的问题。
灰度、预热、慢启动都是避免变更出现问题的比较重要的方式,这里就不展开了。
说一说容量评估,一般来说会做这么几件事儿,第一件事需要确定流量的来源,像是大促活动时需要确定流量是从H5来的还是从第三方的接口来的,来源确定后可以根据过往的经验来设定一个目标值。梳理链路和服务情况是为了结合监控和全链路压测更好地进行容量评估,水位的设定可以帮助判断之前设立的目标值是否合理,看具体是要优化还是扩容,以最终确定我们的机器的数量和和资源的数量。
上文提到的全链路压测,大家感兴趣的可以回顾之前的文章了解详情。
👉二十问全链路压测干货汇总(上)全网最全
做好设计和部署之后就该思考如何通过手段来减少故障发生的机率,主要是有两种方式,1种是冗余,1种是隔离。
冗余包括计算冗余和存储冗余, 存储冗余更多的是使用复制的方式,包括同步复制、半同步复制和异步复制3种。存储冗余本身的复杂度比较高,因为需要把数据从一个地方拷贝到另1个地方,并且要保证数据的完整性。与之相对的是计算冗余,常见的方式是负载均衡服务器和多机房策略。隔离指的是服务隔离,可以根据功能或者重要程度将一个服务拆分成多个子模块,每一个模块之间不会互相影响。这个idea是来源于船舱的设计,大型轮船会有很多的船舱,但它会保障每个船舱是相互隔离的,这样即使某1个船舱出现故障进水了,它只会影响这一个船舱,不会把整个船全部拖垮。那在进行服务隔离的时候,也是这么一个思路,可以选择放弃一部分功能或者服务的稳定性来保证全局的稳定性。
讲了那么多故障的事先预防,那当故障已经发生时,我们又该怎么处理?
你的监控指标是否完善?又该如何制定指标?
你的告警逻辑是正确的么?应该遵循怎么样的告警原则?
怎么样才能快速地进行故障修复?熔断、降级、流控应该怎么做?
想要了解这些问题的详细解答,关注数列科技,回复关键词【71】即可查看原版演讲视频~