若是看过我前面对服务限流的分析,理解服务降级就很容易了,对于一个景区,平时随便进出,可是一到春节或者十一国庆这种状况客流量激增,那么景区会限制同时进去的人数,这叫限流,那么什么是服务降级呢?html
简单来讲就是,将一些不过重要的景区项目砍掉,平时就那么三五八我的,景区能够开放湖中游泳啦,摸鱼啦,捉虾啦,有状况工做人员能够下湖捞你,可是如今客流量大了,工做人员关注不过来,都在湖里晃荡万一沉了不太安全,大手一挥,这个项目砍了,将工做人员分配在其余地方。前端
在互联网中也有相似的降级措施,像以前双11, 有段时间是只容许下单不容许退单或者改单,这样作目的是什么呢?web
仍是为了保证服务的可用性,当硬件软件优化到必定的程度仍是有上限,这时候将资源重点倾斜给核心业务,那些不过重要的就砍掉,保证服务的可用性。redis
服务等级定义 SLA(Service Level Agreement)是断定压测是否异常的重要依据。压测过程当中,经过监控核心服务状态的 SLA 指标数据,能够更直观地了解压测业务的状态。数据库
SLA则是服务商与您达成的正常运行时间保证。后端
关于这个的详细解释,能够参考阿里云的介绍:服务等级定义SLA,这儿不过多描述,SLA 分为网络服务和云服务,提供商的在线保证率一般要求达到6个9。api
6个9指99.9999%,也就是一个服务有99.9999%几率是安全的,6个9有多安全呢?缓存
2个9 = (1-99%)X24 X 365 = 87.6 小时 = 3.65天安全
3个9 = (1-99.9%)X24 X 365 = 8.76 小时服务器
4个9 = (1-99.99%)X24 X 365 = 0.876 小时 = 52.56分钟
5个9 = (1-99.999%)X24 X 365 = 0.0876 小时 = 5.256分钟
6个9 = (1-99.9999%)X24 X 365 = 0.00876 小时 = 0.5256分钟 = 31秒
也就是,一年当中,6个9的安全性最多会有31s服务是不可用,相对来讲是极高的。
这方面有不少例子,好比某些页面挂了会返回寻亲子网。能够对一些关键数据设置一些兜底数据,例如设置默认值、静态值、设置缓存等。
默认值: 设置安全的默认值,不会引发数据问题的值,好比库存为0
静态值:请求的页面或api没法返回数据,提供一套静态数据展现,好比加载失败提示重试,或者寻亲子网,或者跳到默认菜单,给用户一个稍微好一点的体验。
缓存: 缓存没法更新便使用旧的缓存
限流顾名思义,提早对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,再也不调用后续资源,也就是当流量洪峰到达的时候,可能须要丢弃一部分用户来保证服务可用性,对于丢弃的用户能够提供友好的提示,好比提示用户当前繁忙、稍后重试等。
限流须要结合压测等,了解系统的最高水位,也是在实际开发中应用最多的一种稳定性保障手段。当服务器压力剧增的状况下,根据当前业务状况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
对调用的数据设置超时时间,当调用失败时,对服务降级,举个例子,当访问数据已经超时了,且这个业务不是核心业务,能够在超时以后进行降级,好比商品详情页上有推荐内容或者评价,可是能够降级显示评价暂时不显示,这对主要的用户功能——购物,不产生影响,若是是远程调用,则能够商量一个双方均可以接受的最大响应时间,超时则自动降级。
若是远程调用的服务器挂了(网络故障、DNS故障、HTTP服务返回错误),则能够进行降级, 例如返回默认值或者兜底数据或者静态页面,也能够返回以前的缓存数据。
客户端高可用:提供多个可调用的服务地址,这样作
微服务重试:dubbo重试机制
API调用重试:当达到重试次数后,增长访问标记,服务降级,异步探测服务是否恢复。
WEB端:在服务不可用时,web端增长重试按钮或自动重试能够提供更友好的体验。
自动重试需设置重试次数和数据幂等处理
在服务器提供支持期间, 若是监控到线上一些服务存在问题,这个时候须要暂时将这些服务去掉,有时候经过服务调用一些服务,可是服务依赖的数据库可能存在,网卡被打满了,数据库挂了,不少慢查询等等,此时要作的就是暂停相关的系统服务,也就是人工使用开关降级。开关能够放在某地,按期同步开关数据,经过判断开关值来决定是否作出降级。
开关降级还有一个做用,例如新的服务版本刚开发处在灰度测试阶段,不太肯定里面的逻辑等等是否正确,若是有问题应该能够根据开关的值切回旧的版本。
在服务调用方设置一个flag,标记服务是否可用,另外key能够存储存储在在本地,也能够存储在第三方的配置文件中,例如数据库、redis、zookeeper中。
分析机器人行为:短期连续操做,agent,行为轨迹、拖拽(模拟登录/秒杀/灌水)
爬虫:引到到静态页或缓存页
简而言之,在一个请求内,多级缓存架构下,后端缓存或db不可用,可使用前端缓存或兜底数据让用户体验好一点。
对于读服务降级通常采用的策略有:
暂时切换读: 降级到读缓存、降级到走静态化
暂时屏蔽读: 屏蔽读入口、屏蔽某个读服务
一般读的流程为: 接入层缓存→应用层本地缓存→分布式缓存→RPC服务/DB
咱们会在接入层、应用层设置开关,当分布式缓存、RPC服务/DB有问题时自动降级为不调用。固然这种状况适用于对读一致性要求不高的场景。
页面降级、页面片断降级、页面异步请求降级都是读服务降级,目的是丢卒保帅,保护核心线程,或者因数据问题暂时屏蔽。
还有一种是页面静态化场景。
动态化降级为静态化:好比,平时网站能够走动态化渲染商品详情页,可是,到了大促来临之际能够将其切换为静态化来减小对核心资源的占用,并且能够提高性能。其余还有如列表页、首页、频道页均可以这么处理。能够经过一个程序按期推送静态页到缓存或者生成到磁盘,出问题时直接切过去。
静态化降级为动态化:好比,当使用静态化来实现商品详情页架构时,平时使用静态化来提供服务,可是,由于特殊缘由静态化页面有问题了,须要暂时切换回动态化来保证服务正确性。 以上都保证了出问题时有预案,用户能够继续使用网站,不影响用户购物体验。
你们都知道硬盘性能比不上内存性能,若是访问量很高的话,数据库频繁读写可能撑不住,那么怎么办呢,可让内存(假如是Redis)库来暂时知足写任务,同时将执行的指令记录下来,而后将这个信息发送到数据库,也就是不在追求内存与数据库数据的强一致性,只要数据库数据与Redis数据库中的信息知足最终话一致性便可。
也就是说,正常状况下能够同步扣减库存,在性能扛不住时,降级为异步。另外,若是是秒杀场景能够直接降级为异步,从而保护系统。还有,以下单操做能够在大促时暂时降级,将下单数据写入Redis,而后等峰值过去了再同步回DB,固然也有更好的解决方案,可是更复杂,不是本篇的重点。
还有如用户评价,若是评价量太大,那么也能够把评价从同步写降级为异步写。固然也能够对评价按钮进行按比例开放(好比,一些人看不到评价操做按钮)。好比,评价成功后会发一些奖励,在必要的时候降级同步到异步。
总结
在cap原理和BASE理论中写操做存在于数据一致性这个环节,降级的目的是为了提供高可用性,在多数的互联网架构中,可用性是大于数据一致性的。因此丧失写入数据同步,经过上面的理论,咱们也能勉强接受数据最终一致性。高并发场景下,写入操做没法及时到达或抗压,能够异步消费数据/cache更新/log等方式
当系统出现问题的时候,尽可能将请求隔离在离用户最近的位置,避免无效链路访问, 在后端服务部分或彻底不可用的时候,可使用本地缓存或兜底数据,在一些特殊场景下,对数据一致性要求不高的时候,好比秒杀、抽奖等能够作假数据。
在js中埋降级开关,在访问不到达,系统阈值的时候能够避免发送请求
主要控制页面功能的降级,在页面中,经过JS脚本部署功能降级开关,在适当时机开启/关闭开关。
能够在接入层,在用户请求还没到达服务的时候,经过、Nginx + Lua、Haproxy + lua过滤无效请求达到服务降级的目的, 主要控制请求入口的降级,请求进入后,会首先进入接入层,在接入层能够配置功能降级开关,能够根据实际状况进行自动/人工降级。这个能够参考第17章,尤为在后端应用服务出问题时,经过接入层降级从而给应用服务有足够的时间恢复服务。
主要控制业务的降级,在应用中配置相应的功能开关,根据实际业务状况进行自动/人工降级。
SpringCloud中能够经过Hystrix配置中心能够进行人工降级,也能够根据服务的超时时间进行自动降级, Hystrix是Netflix开源的一款针对分布式系统的延迟和容错库,目的是用来隔离分布式服务故障。它提供线程和信号量隔离,以减小不一样服务之间资源竞争带来的相互影响;官网讲Hystrix提供优雅降级机制;提供熔断机制使得服务能够快速失败,而不是一直阻塞等待服务响应,并能从中快速恢复。Hystrix经过这些机制来阻止级联失败并保证系统弹性、可用。下图是一个典型的分布式服务实现。
例如打开淘宝首页,这一瞬间须要加载不少数据,有静态的例如图片、CSS、JS等,也有不少其余商品等等,这么多数据中,若是一部分没有请求到,那么就能够片断降级,意思是就不加载这些数据了,用其余数据顶替,例如其余商品信息或者等等。
这个很容易理解,你们应该都记得,每次双十一以前,淘宝总会提醒你下载更新,按道理来说,活动还没开始,更新啥呢?
作法是对于一部分静态数据能够提早更新到你手机上,当你双十一时就不用再远程链接服务器加载了,避免了消耗网络资源。