首页 > 其他分享 >心法|大型高并发系统的逃生能力架构要如何设计

心法|大型高并发系统的逃生能力架构要如何设计

时间:2023-04-20 10:58:41浏览次数:37  
标签:架构 故障 系统 能力 并发 限流 逃生 服务 心法

故障是无法避免的,所以作为一个大型互联网系统,逃生能力的架构设计尤其重要,一个具备优秀逃生能力的系统,在故障发生后,可以把用户影响降到最低甚至无损,多年在小爱/米家一次次大小故障的处理和复盘中,慢慢形成了一些经验和方法的思考。

大型互联网系统,模块多、依赖关系和运行环境复杂,逃生能力一定是要拿出来当做独立主题来思考设计的,目标是打造一个架构皮实的高可用系统,而不是一个脆皮,一碰就崩。

为了阐述清楚如何建设逃生能力,我总结画了一张打造逃生能力架构的地图(此视角聚焦故障发生后的逃生,而不是预防),整体分为四部分包括有损逃生、无损逃生、工具赋能和一些逃生原则,理论上系统的涵盖了所有场景,要盘点建设逃生能力时,可以一项项的过。

 

大型系统逃生能力地图

1. 有损逃生能力

有损逃生是对用户有感、有损的,但相比系统雪崩无法恢复、全部用户无法使用而言,已经是非常好的结果了,最重要的是他降低了故障影响、并且助力了系统的快速恢复或自愈,为系统完全恢复健康争取了时间,以下5个有损逃生的手段要尽可能用好。

1)限流

限流是一种控制流量的技术,对用户有损,一般在入口进行保护,用于保护系统免受过多的请求或流量的影响,是首先保护好自己、防止系统雪崩的一个基础逃生能力,一定要配备。

它可以防止系统过载,提高系统的可用性和稳定性。限流可以通过多种方式实现,例如基于时间窗口的限流、基于令牌桶的限流、基于漏桶的限流等。在实际应用中,限流通常与负载均衡、缓存、分布式系统等技术一起使用,以提高系统的性能和可靠性。

在大型互联网系统中,抖一下就会带来用户的重试进而流量突增,故障期间更是大量的用户重试和自动重试,流量无异于Ddos攻击,所以限流非常重要,要当做服务的基础能力来设计,每个服务在遇到流量过载时首先要有能力通过限流让自己不挂掉,限流参数在设计上一定要支持云端配置,便于SRE和后端研发在故障期间可以快速操作。

为了避免在日常触发限流影响用户,工程师却不知道,所以要有限流打点,配置触发限流的监控告警,其次限流的阈值是根据系统的吞吐量来动态调整的,要根据压测或者故障演练得到的数据常练常新。

通过以往处理的经验,故障后的第一件事儿往往是限流,做好限流后既能保护好自己,同时也保护了后端依赖不被过载打挂

2)熔断

熔断也是一种重要的逃生能力,微服务中一般都会通过RPC框架实现,他可以对某一下游服务切断请求快速失败,失败后一般再结合自动降级,降低对用户体验和系统的影响,以避免故障扩散、影响到其他服务。

熔断机制通常会设置一个阈值,当系统的某个指标(如请求响应时间、错误率等)超过阈值时,就会触发熔断,快速失败或停止服务一段时间,等待系统恢复正常后再重新开启服务。熔断机制可以提高系统的稳定性和可靠性,避免系统崩溃或雪崩效应。

比如说大家最常用的nginx,他拥有最典型的熔断机制,每个upstream server后面都有max_fails和fail_timeout两条指令,其含义是某个server如果fail_timout时间内出现max_fails次fails本server就被熔断fail_timeout时间不可用,代码实现上是nginx内部有一个对fails的计数,每增加一次错误计数就加1,同时做是否健康判断,当惩罚一个fail_timeout周期后,fails的计数清零,恢复健康,请求重新分发到这台server。

例如在处理米家摄像机故障的实操中,由于重试流量太大(日常nginx的高峰QPS在30万+,故障期间重试QPS 100万+),限流能力暂不完善,服务run起来就挂,全链路扩容抗住故障流量也不是办法,于是我们操作了史上最粗暴的熔断,将用户过来的所有请求全部return 200,将所有路由的所有后端全部手工熔断,让客户端认为请求正常停止重试,然后再一点点将后端接口渐进式放开,逐步恢复业务,所以熔断故障时刻是能救命的。

3)降级

降级也是逃生架构里重要的一环,尤其当发生熔断的时候,特别需要设计好降级的策略

系统降级是指系统在遇到异常情况时,能够自动或手动降低自身的功能或性能,降低服务标准以保证系统的稳定性和可靠性。

同样以nginx举例,上述熔断章节只说了一半,其实还有一半叫做降级,结合业务场景,开启proxy_cahe后有一个proxy_cache_use_stale的指令,可以在后端错误或全部熔断5XX后返回最近一次缓存的结果进行降级,这样一套组合拳下来可以最小程度降低对系统的影响,放一个之前的截图如下。

降级的场景有很多,比如当小爱的一个query错误时,返回默认话术进行降级,再比如在新浪时多次出现评论/点赞流量太大故障,我们就干脆直接把评论/点赞的功能熔断降级,用户虽然无法评论,但依旧可以正常浏览新闻,保障了主干功能不受影响,小爱和米家还有很多类似的设计,最大程度降低用户影响、降低故障蔓延、提高系统的高可用。

4)隔离

故障隔离是指系统发生故障时,能够将故障封闭隔离在最小的单元空间里,避免故障蔓延、发生雪崩,保证健康的部分能够正常运行,是一个非常实用的夯实系统逃生能力的手段。

比如说c3机房故障,在没有确定c4机房有足够容量进行流量切换前,架构上可以使故障只隔离封闭在c3机房,c4机房的用户可以正常响应;比如说多个服务混跑的共同的机器上,一个服务异常了就会影响其它,就要想办法把某些服务隔离部署开,避免相互影响;比如说所有的接口都跑在一个nginx大集群里,有些接口性能差、流量大还经常突增,影响到其他,就要想办法分群,把某些接口隔离分开;再比如数据库的分库分表虽然是为了解决性能问题,但同样解决了故障隔离的问题。同样道理用于产品功能和各种各样的场景。

隔离是为了逃生,不隔离为了共享资源,两者是一对对立与统一的矛盾体。全部隔离最安全但资源、研运成本也最高,有些其实没必要隔离;全部共享成本最低,但服务中有一颗“老鼠屎”,整个服务可能就会雪崩全部挂掉。

对于怎么隔离,也是有一些方法论的,可以看几个维度,1个维度是把服务进行分级,一级服务肯定是要重点保障的;1个维度是要识别出问题服务,性能差、流量大还经常突增的肯定要单独拿出去的,避免“一颗老鼠屎,坏了一锅汤”;1个维度是识别体量,体量太大后未知风险和问题随之都会随之增大,这个时候要想办法在出问题前化整为零,将大服务拆分隔离成一些小服务小集群。

举两个实操例子,小爱协同唤醒功能在稳定前,经常会因客户端的一个bug周期性流量突增,由于复用了小爱语音的一些公共组件,导致每次故障发生后整个小爱都不可用,考虑后,我们将协同唤醒使用的资源和服务全部隔离出来,现在再出问题只影响协同唤醒功能,主干功能不受影响;再比如米家的结构化存储一直使用小米自研的SDS(基于hbase研发),多年来一直在通过扩容提高容量和性能,在集群规模接近3Pb、高峰写QPS达到55万后服务开始变得不稳定,经常抖动,而且出问题后存储的恢复时间都比较长,经过分析后,我们采用了分群隔离化整为零的策略,分业务拆分成了几个小集群,改造完成后服务恢复稳定。

5)容错

容错能力是系统对错误的兼容能力,我这里考虑的更多是架构和功能层面的容错,避免出现一点错误系统就不可用崩掉

架构层面,比如说服务对注册中心的依赖,当注册中心挂了后,是否可以做到不影响存量调度,只影响新注册和发布,其实完全是可以的,只要把注册路由表在本地有一个存一份的机制即可,这是一个最常规的对注册中心的容错。

功能层面,比如说服务传进来一个非法参数,是否有验证机制快速失败和提示报错,不会让系统卡主、宕机,对错误兼容,而不是让错误继续蔓延,进而造成整个系统堵塞不可用。

一个经验丰富老道的研发工程师可以把容错能力做到极致,避免了很多的潜在故障,相反如果容错能力差,就像一个裸露在雨天的房子,到处都在漏雨,随时可能塌方,所以容错做好绝对可以大大提升系统的逃生能力。

2. 无损逃生能力

无损逃生在架构上要重点设计,灾备和弹性如果做的好,故障发生后理想情况下是可以让用户做到无感的,特别是容灾,故障发生后结合快速切换,系统本身可以基本做到无损逃生。

1)灾备

灾备的本质是通过增加成本使用高可用技术赋予系统“三头六臂、千手千脚”,当某个部位有故障时,随时有备用的顶上,是逃生架构中最常用的手段。

在备用资源足够的情况下,灾备考验的是故障转移的能力,其中最理想的情况是自动转移,最典型的例子是网络专线,一般两个区域的专线都是成对的,而且走不一样的路径,一旦一条专线断了,用几秒的时间快速进行路由收敛,切换到备用专线,整个过程完全自动,所以时常会看到网络专线断掉已自动切换不影响业务的公告,可是说是逃生架构设计的样板

而大型互联网系统的灾备要复杂的多,我们一般将灾备分为冷备、热备、读写分离、多活几个段位,其中多机房异地多活是最理想的架构。单实例多活可以用负载均衡、注册中心等结合健康机制实现,但机房间灾备就要面对很多新的技术难点了,用钱堆IaaS层的两地三中心容易,但多活真正的挑战在上层。

多活最难实现的其实是数据层,比如说mysql,虽然功能上支持多主多写,但一旦上到生产环境,脑裂的情况依旧没办法很好的解决,而大多数业务又是要求数据强一致性,比如说数据库里存着用户余额,不能请求到了不同机房数据不一致了,所以依旧以机房间读写分离的架构为主,类似上述情况的数据库系统有很多,所以米家我们现在做到的还是应用层3机房多活,数据层MySQL、redis这些只能暂时做到读写分离甚至热备。

基于这个现状,我们的目标一定要往高分上做,不能因为某些业务暂时做不到多活灾备就不做了,而是要根据业务情况分而治之,分服务能做多活的不做热备、能做热备的不做冷备,能做到90分不要做到80分,分数越高高可用性肯定也是越好的,灾备和成本也是一对矛盾体,需要从公司资源层面找到平衡。

故障切换能力本身放到现在已经不是什么难点了,接入层有域名Dns、HttpDns、负载均衡,应用层有注册中心/配置中心,但需要使用工具赋能提升切换操作效率,灾备做好,故障发生后真的可以很从容,所以逃生架构设计上一定要把灾备考虑到,要以多机房异地多活为目标。

2)弹性

弹性是有了云和容器后应运而生的一种能力,在遇到系统过载的场景时可以使用弹性能力快速扩容,从小爱/米家的经验看,在出故障时,真的是手头能弄到多少资源就扩多少,不管能不能根本解决问题,多多益善,先扩上再说,传统的物理机模式,资源备货和扩容本身是阻碍弹性的两个重大卡点,后面有了自建k8s,服务扩容本身的问题解决了,但把弹性压力转移到了k8s团队,node节点的资源备货和快速扩容在自建机房依然是个大问题。

因为大厂基本都有自己的机房(体量上来后自建机房还是有很大成本优势的,过保的机器也可以给一些不重要的业务接着用,在新浪当时就经常看到服务器“10年老员工”,小米现在陆续也能看到了),所以在设计上,最好在自建机房保障常规资源的基础上,加装上公有云作为弹性逃生资源做成混合云的架构后使整个系统具备弹性能力,再结合自动化的技术在故障期间快速扩容,比如现在阿里云的ACK+ECI真的是非常方便。

弹性对业务的架构也提出了新的要求,一是要支持混合云,特别是要把PaaS层处理好,云上和云下PaaS异构对代码的挑战太大了,而且业务本身要支持简单快速的横向扩展,服务尽量无状态,能容器化的尽量容器化,这里也有个循序渐渐地过程,能容器化(公司内部自建k8s)的尽量不走物理机部署,能混云的尽量不只在自己的IDC部署,比如阿里云虽然可以通过ECS进行虚拟机弹性,但相比而言ACK+ECI的模式一步到位更香。

所以弹性能力一旦具备,在出现突发活动系统过载和各种故障时是可以大大降低恢复时间的,大多数的故障扩容都是有用的,而且有了弹性对于像米粉节/618/双十一这种大促活动,重保前的扩容、重保后的缩容都工作可以轻松很多。

3. 逃生工具赋能

工具是为了提升逃生效率的,故障期间分秒必争,仅靠工程师人肉操作,太耽误时间了,所以必须用工具为逃生操作赋能。

1)故障发现定位能力

发现故障和定位故障点是老生常谈的能力,他是故障逃生能力的一个基础,大多数的故障只有发现了、定位到了故障点(支持执行预案即可),才知道怎么执行预案恢复,即使刚好触碰到有故障自愈能力的部分,也需要知道线上发现了什么,才便于问题的彻底修复。

常用故障发现和定位的解法是告警、监控、日志分析等,前面多处章节都做了讲解,我们在生死告警、告警分析、故障诊断、链路监控都做了最佳实践,并在之前的博客中都有分享,就不拆开看了,故障发现定位工具是一些必备的基础工具。方向上,告警要少、准、快、全,定位要快、准。

2)运维预案执行能力

预案执行的工具是非常非常重要的,最理想的终态是所有故障场景都能够通过工具自动化执行预案、系统能够自愈,但目前看要覆盖所有场景还是需要一个很长的过程,从IaaS层、PaaS层到系统代码,故障场景太多了,现实离通过系统自动诊断出根因进而自动执行准确的预案还有不少距离,很多场景还需要SRE和研发具体问题具体分析后再对症下药,甚至很多故障在执行了各种预案恢复后,还是不知道根因,只知道很粗的大概原因,需要事后再花不少时间做复盘分析,大型互联网系统的生产环境,比想象中要复杂很多。

但是所有的现状并不妨碍我们向北极星的方向前进,要尽量识别出更多的、更常见的故障场景,提前准备好预案做到工具里,能够做成自动化预案的尽量不要工程师参与,需要工程师参与的尽量在工具里形成一键操作的剧本。比如说对于磁盘空间用满的场景我们已经彻底使用工具解决实现自愈,之前的博客有分享;同一机房不同链路的出口故障也很标准化了,可以使用工具自动切换;单实例故障的自愈可以通过负载均衡、注册中心结合健康检查彻底解决。

除工具外再多说一点,预案的执行还体现在工程师的组织能力上,工程师的响应及时、配合有序、快速决断、执行高效同样非常重要,前面有一篇博客专门讲了如何处理一个大型互联网系统的突发故障,工具能力体现了一个自动化水平,两者相辅相成,浑然一体,出故障时才能快速逃生。

在工具系统的设计上也是有一些方法论的,虽然没办法穷举所有故障场景的预案,但是可以识别到有6个原子预案——重启、回滚、扩容、切流、降级、限流(前面有章节专门介绍),第一步可以将这些操作收敛到尽量少的工具里,当然前提是所有服务首先得具备上述能力,复杂的预案基本都是围绕原子预案进行排列组合做成的剧本,先有这样的技术工具,再一步步往自愈、自动执行预案的方向走。

4. 一些逃生架构设计原则

1) 系统无点单故障

这里的单点特指实例维度,在设计系统的逃生能力时,有一个基本原则:每个模块起码做到无单实例的单点故障,流量再小但至少也要做到两个实例跑在两台不同服务器上的最小容灾(服务器宕机是一个常规且不可避免的事情)。

消除单点,某台服务器挂了其他的服务器才能把活儿接起来,否则完全没有高可用性而言。

2)上层保护下层,下层不信任上层

这个原则是米家616故障复盘时,来自小米郑闫强老师总结的,我觉得很好就拿过来了,之前对于架构中上下游的关系有一些约定俗成的做法,但一直没有总结成这么一句话。

理解上很简单,上层的服务要有对下层服务保护的义务,比如说已经识别到因异常流量过载,就不要把流量再分发到下层了,同样下层服务对于上层也不能完全信任,要做好限流、降级保护好自己不挂掉

写到这里,希望对你有所帮助!!!

标签:架构,故障,系统,能力,并发,限流,逃生,服务,心法
From: https://www.cnblogs.com/netflix/p/17335968.html

相关文章

  • 心法| 如何高效处理一个大型互联网系统的突发故障?
    故障处理troubleshooting是做互联网SRE最心跳的事情,没有之一,也是考验一个SRE是否能够独挡一面的最有效方式。首先它的发生是随机的,完全未知,尤其是大型互联网系统,海量的用户,故障发生后精神高度紧张,要顶着巨大的压力,用最短的时间协同各方制定方案、恢复业务,尤其考验一个人的综合素......
  • 心法|SRE如何制定科学有用的流程制度
    科学的制定流程制度是非常重要的,好的流程制度能提高生产效率、降低出错,但流程制度用不好是要阻碍创新的,甚至引起工程师的反感和抵触。比如为了减少工程师出错,把工作的每个角落铺满精细的流程制度规范,每个制度事无巨细的几千上万字,无异于对工程师缚手缚脚,大家也背不过来,唯一的用途......
  • 一种面向后端的微服务低代码平台架构设计
    作者:京东科技 常姜洲一、背景近期参加公司组织的极客中餐厅训练营,我们所在的小组接到的课题是微服务的低代码平台架构设计。目标是:结合京东业务研发实际情况,针对后端研发人员,设计一个微服务低代码平台,助力更高效低交付业务需求。现已结业,将我在本次项目中沉淀设计出的设计文档整理......
  • Java架构师面试题
    Java架构师面试题以下是一些Java架构师面试题的示例:请谈谈你对Java多线程的理解,并介绍一下Java线程池的使用场景。请谈谈你在项目中遇到的最困难的问题是什么,以及你是如何解决的?请谈谈你对Spring框架的理解,并介绍一下Spring的核心模块和作用。请简述一下你对RESTfulAPI的认......
  • Java架构师在项目中的经验
    好的,以下是一个更详细的Java架构师在项目中的经验描述:项目名称:XXX系统项目描述:该项目是一个基于微服务架构的电商平台,涵盖了商品管理、订单管理、支付管理、会员管理等多个模块。作为Java架构师,负责系统的整体设计和开发工作。项目职责:负责制定系统的整体架构和技术方案,根据业......
  • Java架构师在项目中的经验描述示例
    以下是一个Java架构师在项目中的经验描述示例:项目名称:XXX系统项目描述:该项目是一个基于微服务架构的电商平台,涵盖了商品管理、订单管理、支付管理、会员管理等多个模块。作为Java架构师,负责系统的整体设计和开发工作。项目职责:设计并实现了整个系统的微服务架构,包括服务拆分、......
  • 资深Java架构师简历
    资深Java架构师简历以下是一个资深Java架构师的简历示例:姓名:李四联系方式:12345678901|[email protected]职业目标:资深Java架构师教育背景:本科学位,计算机科学与技术专业,清华大学,2005年毕业技能与经验:15年以上Java开发经验,熟悉Spring、MyBatis等主流框架精通数据库设计和优......
  • Java架构师简历
    以下是一个Java架构师的简历示例:姓名:张三联系方式:12345678900|[email protected]职业目标:Java架构师教育背景:本科学位,计算机科学与技术专业,清华大学,2010年毕业技能与经验:10年以上Java开发经验,熟悉Spring和Hibernate框架精通数据库设计和优化,能够使用Oracle、MySQL等主......
  • Java架构师项目经验历史最详细版本
    Java架构师项目经验历史最详细版本好的,以下是一个Java架构师在项目中的历史最详细版本的经验描述:项目名称:XXX系统项目描述:该项目是一个基于微服务架构的电商平台,涵盖了商品管理、订单管理、支付管理、会员管理等多个模块。作为Java架构师,负责系统的整体设计和开发工作。项目职......
  • 简单介绍十几款常用的画架构图流程图的软件
    简单介绍十几款常用的画架构图流程图的软件draw.iodraw.io是开源免费的在线画图工具,还提供桌面版本。特性:实时协作;支持在线离线版本;存储支持多种方式:GoogleDrive,OneDrive,GitHub,GitLab,Dropbox等;许多丰富的图标库。ProccessOnProccessOn是一款优秀的国产在线协......