高可用之——降级

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/l1028386804/article/details/101019153

降级的最终目的是保证核心服务可用,即使是有损的。有些服务器无法降级(加入购物车、结算等)。降级也需要根据系统的吞吐量、响应时间、可用率等条件进行手工降级或自动降级。

降级预案

降级可以参考日志级别设置降级预案,如下:

  • 一般:有些服务偶尔因为网络抖动或服务正在上线而超时,可以自动降级。
  • 警告:有些服务在一段时间内成功率有波动(比如在95%~100%之间),可以自动降级或人工降级,并发送告警。
  • 错误:比如:可用率低于90%,或者数据库连接池用完了,或者访问量突然猛增到系统能承受的最大阈值,此时,可以根据情况自动降级或人工降级。
  • 严重错误:比如:因为特殊原因数据出现错误,需要紧急人工降级。

降级按照是否自动化可分为:自动开关降级和人工开关降级。
降级按照功能可分为:读服务降级和写服务降级。
降级按照处于的系统层次可分为:多级降级。

降级的功能点主要从服务端链路考虑,根据用户访问的服务调用链路梳理哪里需要降级。

  • 页面降级:在大促或者某些特殊情况下,某些页面占用了一些稀缺服务资源,在紧急情况下可以对其整个降级,达到丢卒保帅的目的。
  • 页面片段降级:拨入:商品详情页的商家部分因为数据错误,此时,需要对其进行降级。
  • 页面异步请求降级:比如,商品详情页上有推荐信息/配送至等异步加载的请求,如果这些信息响应慢或者后端服务有问题,则可以进行降级。
  • 服务功能降级:比如:渲染商品详情页时,需要调用一些不太重要的服务(相关分类、热销榜等),而这些服务在异常情况下直接不获取,即降级即可。
  • 读降级:比如:多级缓存模式,如果后端服务有问题,则可以降级为只读缓存,这种方式适用于对读一致性要求不高的场景。
  • 写场景:比如:秒杀抢购,我们可以只进行Cache更新,然后异步扣减库存到DB,保证最终一致性即可,此时可以将DB降级为Cache。
  • 爬虫降级:比如:在大促时,可以将爬虫流量导向静态页或者返回空数据,从而保护后端稀缺资源。
  • 风控降级:比如:抢购/秒杀等业务,完全可以识别机器人、用户画像或者根据用户风控级别进行降级处理,直接拒绝高风险用户。

自动降级开关

自动降级是根据系统负载、资源使用情况、SLA等指标进行降级。
1.超时降级
当访问的数据库/HTTP服务/远程调用响应慢或者长时间响应慢,且该服务不是核心服务的话,可以在超时后自动降级。
注意:在实际场景中一定要配置好超时时间和超时重试次数及机制。

2.统计失败次数降级
有些依赖一些不稳定的API,比如,调用外部的第三方服务,当失败调用次数达到一定阈值自动降级(熔断器)。然后通过异步线程去探测服务是否恢复了,恢复则取消降级。

3.故障降级
比如,要调用的服务挂掉了,可以直接降级。降级后的处理方案有:默认值(库存服务故障,返回默认有货)、兜底数据(广告挂了,返回提前准备好的静态页面)、缓存(之前缓存的一些缓存数据)。

4.限流降级
秒杀或抢购业务,可能会因为访问量太大导致系统崩溃,可以使用限流限制访问量,达到限流阈值时,后续请求被降级。降级后的处理方案有:排队页面(将用户导流到排队页面等一会重试)、无货(直接告知用户没货了)、错误页(活动太火爆,稍后重试)。

人工开关降级

如果线上一些服务存在问题,需要暂时将这些服务摘掉。如果调用量太大,可能需要改变处理方式(同步转换为异步)。可以使用开关来完成降级,开关可以存放到配置文件、数据库、Redis或者Zookeeper。如果不是存放在本地,可以定期开关数据(比如1秒同步一次)。然后,通过判断某个Key的值来决定是否降级。

当新服务有问题时可以通过开关切换回老服务,再有就是多机房服务,如果某个机房挂了,需要将一个机房的服务切到另一个机房,此时,也可以通过降级开关完成切换。

如果因为功能问题需要暂时屏蔽掉某些功能,此时需要开关控制降级。

读服务降级

一般策略有:暂时切换读(降级到读缓存、降级到走静态化)、暂时屏蔽读(屏蔽读入口、屏蔽某个读服务)。
页面降级、页面片段降级、页面异步请求降级,都是读服务降级。
动态页面降级为静态化:调用量太大时,可以将动态页面降级为静态化,通过一个程序定期推送静态页到缓存或者生成到磁盘,出问题时直接切过去。
静态化降级为动态化:静态化出问题时,可以暂时切换到动态化保证服务的正确性。

写服务降级

写服务大多数场景不可降级,但是可以将同步写操作转换为异步写数据,或者限制写的量/比例。
比如扣将库存的场景:
方案1:
扣减库存,扣减成功后,更新Redia库存。
方案2:
扣减Redis库存,同步扣减DB存库,如果扣减失败,则回滚Redis库存。
这两种方案非常依赖DB,如果DB性能跟不上,则扣减库存就会遇到问题,此时可以使用方案3。
方案3:
扣减Redis库存,正常同步扣减DB库存,性能扛不住时,降级为发送一条扣减DB库存的消息,然后异步进行DB库存扣减实现最终一致性。
方案3中发送扣减库存消息可能成为瓶颈,此时可以使用方案4。
扣减Redis库存,正常同步扣减DB库存,性能扛不住时降级为写扣减DB库存消息到本机,然后本机通过异步进行DB库存扣减实现最终一致性。

秒杀场景可以直接降级为异步,保护系统,下单操作可以在大促时暂时降级,将下单数据写入Redis,等峰值过去再同步回DB。

多级降级

缓存离用户越近越高效,降级则是离用户越近越对系统保护的好。

  • 页面JS降级开关:主要控制页面功能的降级,在页面中,通过JS脚本部署功能降级开关,在适当时机开启/关闭开关。
  • 接入层降级开关:主要控制请求入口的降级,请求进入后,会首先进入接入层,在接入层可以配置功能降级开关,可以根据实际情况进行自动降级/人工降级。
  • 应用级降级开关:主要控制业务的降级,在应用中配置相应的功能开关,根据实际业务情况进行自动/人工降级。

配置中心

如果涉及的服务器/系统较少,则初期可以考虑使用配置文件进行配置。如果涉及的服务器/系统较多,则应该使用配置中心进行配置,实现时要做到不需要修改代码。不需要重启应用即可动态配置开关。

  • 在应用层进行API封装
  • 使用配置文件实现开关降级
  • 使用配置中心实现开关降级,可以使用Consul

使用Hystrix实现降级
使用Hystrix实现熔断

关于熔断需要知道如下几个概念

  • 闭合(Closed):如果配置了熔断开关强制闭合,或者当前请求失败率没有超过失败率阈值,则熔断开关处于闭合状态,不启动熔断机制,即不进行降级处理。
  • 打开(Open)L如果配置了熔断开关强制打开,或者当前失败率超过失败率阈值,则熔断开关打开,启动熔断机制,根据配置调用降级处理方法getFallback进行降级处理。
  • 半打开(Half-Open):当熔断处于打开状态后,不能一直熔断下去,需要在一个时间窗口后进行重试,这种状态就是半打开。Hystrix允许在circuitBreakerSleepWindowInMilliseconds窗口内进行一次重试,重试成功则闭合熔断开关,否则熔断开关还是处于打开状态。

注意:重点掌握Hystrix框架。

——总结自涛哥的《亿级流量网站架构核心技术》

猜你喜欢

转载自blog.csdn.net/l1028386804/article/details/101019153