顺昌网站建设wzjseo,浙江搜索引擎优化,网站建设结构设计方案,3合1网站建设价格2019独角兽企业重金招聘Python工程师标准 高并发系统之降级特技 博客分类#xff1a; 架构 在开发高并发系统时有三把利器用来保护系统#xff1a;缓存、降级和限流。之前已经有一些文章介绍过缓存和限流了。本文将详细聊聊降级。当访问量剧增、服务出现问题 高并发系统之降级特技 博客分类 架构 在开发高并发系统时有三把利器用来保护系统缓存、降级和限流。之前已经有一些文章介绍过缓存和限流了。本文将详细聊聊降级。当访问量剧增、服务出现问题如响应时间慢或不响应或非核心服务影响到核心流程的性能时仍然需要保证服务还是可用的即使是有损服务。系统可以根据一些关键数据进行自动降级也可以配置开关实现人工降级。本文将介绍一些笔者在实际工作中遇到的或见到过的一些降级方案供大家参考。 降级的最终目的是保证核心服务可用即使是有损的。而且有些服务是无法降级的如加入购物车、结算。 降级预案 在进行降级之前要对系统进行梳理看看系统是不是可以丢卒保帅从而梳理出哪些必须誓死保护哪些可降级比如可以参考日志级别设置预案 一般比如有些服务偶尔因为网络抖动或者服务正在上线而超时可以自动降级 警告有些服务在一段时间内成功率有波动如在95~100%之间可以自动降级或人工降级并发送告警 错误比如可用率低于90%或者数据库连接池被打爆了或者访问量突然猛增到系统能承受的最大阀值此时可以根据情况自动降级或者人工降级 严重错误比如因为特殊原因数据错误了此时需要紧急人工降级。 降级按照是否自动化可分为自动开关降级和人工开关降级。 降级按照功能可分为读服务降级、写服务降级。 降级按照处于的系统层次可分为多级降级。 降级的功能点主要从服务端链路考虑即根据用户访问的服务调用链路来梳理哪里需要降级 页面降级在大促或者某些特殊情况下某些页面占用了一些稀缺服务资源在紧急情况下可以对其整个降级以达到丢卒保帅 页面片段降级比如商品详情页中的商家部分因为数据错误了此时需要对其进行降级 页面异步请求降级比如商品详情页上有推荐信息/配送至等异步加载的请求如果这些信息响应慢或者后端服务有问题可以进行降级 服务功能降级比如渲染商品详情页时需要调用一些不太重要的服务相关分类、热销榜等而这些服务在异常情况下直接不获取即降级即可 读降级比如多级缓存模式如果后端服务有问题可以降级为只读缓存这种方式适用于对读一致性要求不高的场景 写降级比如秒杀抢购我们可以只进行Cache的更新然后异步同步扣减库存到DB保证最终一致性即可此时可以将DB降级为Cache。 爬虫降级在大促活动时可以将爬虫流量导向静态页或者返回空数据从而降级保护后端稀缺资源。 自动开关降级 自动降级是根据系统负载、资源使用情况、SLA等指标进行降级。 超时降级 当访问的数据库/http服务/远程调用响应慢或者长时间响应慢且该服务不是核心服务的话可以在超时后自动降级比如商品详情页上有推荐内容/评价但是推荐内容/评价暂时不展示对用户购物流程不会产生很大的影响对于这种服务是可以超时降级的。如果是调用别人的远程服务和对方定义一个服务响应最大时间如果超时了则自动降级。 之前总结过一些的文章《使用httpclient必须知道的参数设置及代码写法、存在的风险》和《dbcp配置及jdbc超时设置总结》。在实际场景用一定主要配置好超时时间和超时重试次数和机制。 统计失败次数降级 有时候依赖一些不稳定的API比如调用外部机票服务当失败调用次数达到一定阀值自动降级然后通过异步线程去探测服务是否恢复了则取消降级。 故障降级 比如要调用的远程服务挂掉了网络故障、DNS故障、http服务返回错误的状态码、rpc服务抛出异常则可以直接降级。降级后的处理方案有默认值比如库存服务挂了返回默认现货、兜底数据比如广告挂了返回提前准备好的一些静态页面、缓存之前暂存的一些缓存数据。 限流降级 当我们去秒杀或者抢购一些限购商品时此时可能会因为访问量太大而导致系统崩溃此时开发者会使用限流来进行限制访问量当达到限流阀值后续请求会被降级降级后的处理方案可以是排队页面将用户导流到排队页面等一会重试、无货直接告知用户没货了、错误页如活动太火爆了稍后重试。 人工开关降级 在大促期间通过监控发现线上的一些服务存在问题这个时候需要暂时将这些服务摘掉还有有时候通过任务系统调用一些服务但是服务依赖的数据库可能存在网卡被打满了、挂掉了或者很多慢查询此时需要暂停下任务系统让服务方进行处理还有发现突然调用量太大可能需要改变处理方式比如同步转换为异步此时就可以使用开关来完成降级。开关可以存放到配置文件、存放到数据库、存放到Redis/ZooKeeper如果不是存放在本地可以定期同步开关数据比如1秒同步一次。然后通过判断某个KEY的值来决定是否降级。 另外对于新开发的服务想上线进行灰度测试但是不太确定该服务的逻辑是否正确此时就需要设置开关当新服务有问题可以通过开关切换回老服务。还有多机房服务如果某个机房挂掉了此时需要将一个机房的服务切到另一个机房此时也可以通过开关完成切换。 还有一些是因为功能问题需要暂时屏蔽掉某些功能比如商品规格参数数据有问题数据问题不能用回滚解决此时需要开关控制降级。 读服务降级 对于读服务降级一般采用的策略有暂时切换读降级到读缓存、降级到走静态化、暂时屏蔽读屏蔽读入口、屏蔽某个读服务。在《应用多级缓存模式支撑海量读服务》中曾经介绍过读服务即接入层缓存--应用层本地缓存--分布式缓存--RPC服务/DB我们会在接入层、应用层设置开关当分布式缓存、RPC服务/DB有问题自动降级为不调用。当然这种情况适用于对读一致性要求不高的场景。 页面降级、页面片段降级、页面异步请求降级都是读服务降级目的是丢卒保帅比如因为这些服务也要使用核心资源、或者占了带宽影响到核心服务或者因数据问题暂时屏蔽。 还有一种是页面静态化场景 动态化降级为静态化比如平时网站可以走动态化渲染商品详情页但是到了大促来临之际可以将其切换为静态化来减少对核心资源的占用而且可以提升性能其他还有如列表页、首页、频道页都可以这么玩可以通过一个程序定期的推送静态页到缓存或者生成到磁盘出问题时直接切过去 静态化降级为动态化比如当使用静态化来实现商品详情页架构时平时使用静态化来提供服务但是因为特殊原因静态化页面有问题了需要暂时切换回动态化来保证服务正确性。 以上都保证出问题了有预案用户还是可以使用网站不影响用户购物。 写服务降级 写服务在大多数场景下是不可降级的不过可以通过一些迂回战术来解决问题。比如将同步操作转换为异步操作或者限制写的量/比例。 比如扣减库存一般这样操作 方案1 1、扣减DB库存2、扣减成功后更新Redis中的库存 方案2 1、扣减Redis库存2、同步扣减DB库存如果扣减失败则回滚Redis库存 前两种方案非常依赖DB假设此时DB性能跟不上则扣减库存就会遇到问题因此我们可以想到方案3 1、扣减Redis库存2、正常同步扣减DB库存性能扛不住时降级为发送一条扣减DB库存的消息然后异步进行DB库存扣减实现最终一致即可 这种方式发送扣减DB库存消息也可能成为瓶颈这种情况我们可以考虑方案4 1、扣减Redis库存2、正常同步扣减DB库存性能扛不住时降级为写扣减DB库存消息到本机然后本机通过异步进行DB库存扣减来实现最终一致性。 也就是说正常情况可以同步扣减库存在性能扛不住时降级为异步另外如果是秒杀场景可以直接降级为异步从而保护系统。还有如下单操作可以在大促时暂时降级将下单数据写入Redis然后等峰值过去了再同步回DB当然也有更好的解决方案但是更复杂不是本文的重点。 还有如用户评价如果评价量太大也可以把评价从同步写降级为异步写。当然也可以对评价按钮进行按比例开放比如一些人的看不到评价操作按钮。比如评价成功后会发一些奖励在必要的时候降级同步到异步。 多级降级 缓存是离用户最近越高效而降级是离用户越近越能对系统保护的好。因为业务的复杂性导致越到后端QPS/TPS越低。 页面JS降级开关主要控制页面功能的降级在页面中通过JS脚本部署功能降级开关在适当时机开启/关闭开关 接入层降级开关主要控制请求入口的降级请求进入后会首先进入接入层在接入层可以配置功能降级开关可以根据实际情况进行自动/人工降级这个可以参考《京东商品详情页服务闭环实践》尤其在后端应用服务出问题时通过接入层降级从而给应用服务有足够的时间恢复服务 应用层降级开关主要控制业务的降级在应用中配置相应的功能开关根据实际业务情况进行自动/人工降级。 http://jinnianshilongnian.iteye.com/blog/2306477 转载于:https://my.oschina.net/xiaominmin/blog/1599198