首先,我们需要明确一下这些名词出现的场景:分布式高并发环境。如果你的产品看起来不好看,没人关心它,那么它就不需要这些属性。低并发系统不加任何东西也能很好的工作。分布式系统是一个整体,调用关系错综复杂。如果某个资源出现异常,极有可能会引发连锁故障。当系统承受过载压力时,容器或宿主机将极其脆弱。负载激增、拒绝响应甚至雪崩都会造成严重后果。鉴于分布式系统的病态女孩式响应,我们有多种方法来处理这些异常。接下来,我们将简单介绍一下这些场景,以及常用的方法。1.限流“我的帖子被限流了!”即使你不是互联网从业者,也可以很肯定地说出这句话。他这么说,不是说高并发限流,顺理成章。在web开发中,tomcat默认有一个200的线程池,当请求多了,没有新的线程可以处理请求时,请求会一直在浏览器端等待。表现形式是浏览器一直在旋转(不超过acceptCount),即使你请求一个简单的Helloworld。您可以将此过程视为限流。本质上就是给资源数量设置一个上限,超过这个上限的请求会被缓存或者直接失败。对于高并发场景下的限流,它有特殊的意义:主要用于保护底层资源。如果你想调用一些服务,你需要先获得调用它的权限。限流一般由服务提供者提供,限制调用者做事的能力。比如某服务为A、B、C提供服务,但是根据事先申请的流量预估,服务A的请求限制为1000/秒,服务B为2000/秒,服务C为1w/第二。同时,部分客户端可能拒绝了请求,而部分客户端可以正常运行,限流作为服务端的自我保护能力。常见的限流算法有:计数器、漏桶、令牌桶等,但计数器算法无法实现平滑限流,因此在实际应用中很少使用。2.断路器一般来说,皇帝想要在微服务中过上舒适的夜生活,可以大展拳脚,又不会因为私事丢了江山,所以不得不依赖断路器。熔断的作用主要是避免服务雪崩。如图,A→B→C依次调用,但是C工程可能出现问题(流量过大或者报错等),导致线程永远等待,导致整个链接层被拖累,线程资源被耗尽。顾名思义,熔断器就像保险丝一样,超过负载时保险丝就会烧坏。当然,等后端服务缓和了,我们就可以重新连接了。熔断功能一般由调用方提供,用于不重要的旁路请求,防止这些不重要的业务因异常或超时影响正常和重要的业务逻辑。在实现上,我们可以把融合看作是一种代理模型。当开启熔断时,服务将暂停对其受保护资源的访问,并返回一个固定的或默认的结果,不会进行远程调用。3.降级降级是一个相当模糊的术语。限流熔断在一定程度上也可以看作是一种退化。但通常所说的降级,是指切入级别更高级。降级一般考虑分布式系统的完整性,从源头上切断流量来源。比如双11期间,为了保证交易系统,会暂停一些不重要的服务,避免资源争用。服务降级是人工参与,人为造成部分服务不可用,多为业务降级方式。降级的最佳位置在哪里?入口处。比如Nginx,比如DNS等。在一些互联网应用中,会有MVP(MinimumViableProduct)的概念,也就是最小可行产品,它的SLA要求非常高。围绕最小可行产品,会有一系列的服务拆分操作,当然有些情况甚至需要重写。例如,一个电子商务系统,在极端情况下,只需要展示产品并进行销售。其他一些支持系统,如评论、推荐等,可以暂时关闭。在物理部署和调用关系上,必须考虑这些情况。4、请参考以下情况进行预热。高并发环境下的DB在进程挂掉后重启。由于业务高峰期,对上游负载均衡策略进行了重新分配。刚启动的DB瞬间收到了1/3的流量,然后负载疯狂飙升,直到没有任何响应。原因是:对于新启动的DB,各种??缓存还没有准备好,系统状态和正常运行时完全不一样。大概平时用量的1/10就可以把它弄死。同样,对于一个刚启动的JVM进程,由于字节码没有经过JIT编译器的优化,刚启动时所有接口的响应时间都比较慢。如果不考虑新启动的情况,调用它的负载均衡组件,1/n的流量正常路由到这个节点,容易出问题。因此,我们希望负载均衡组件能够根据JVM进程的启动时间动态缓慢增加量,对服务进行预热,直到达到正常的流量水平。5.背压考虑以下两种情况:没有限流。如果请求量过大,想充多少就充多少,容易造成后端服务崩溃或者内存溢出传统限流。你强行规定了一个接口的最大承载能力,超过了直接拒绝,但是此时后端服务是有能力处理这些请求的。如何动态修改限流值?这就需要一套机制。主叫方需要知道被叫方的处理能力,即被叫方需要有反馈的能力。背压,英文BackPressure,其实是一种智能限流,指的是一种策略。采用反压思想,被请求方不会直接丢弃请求端的流量,而是不断反馈自己的处理能力。请求者根据这些反馈实时调整发送频率。一个典型的场景是在TCP/IP中使用滑动窗口进行流量控制。反应式编程(Reactive)是观察者模式的集大成者。大多采用事件驱动、非阻塞的弹性应用,基于数据流的弹性传输。在这种情况下,背压实现要简单得多。背压使系统更稳定,利用率更高。它具有更高的弹性和智能。总结简单总结一下:限流设置了一个上限,当流量超过系统的承载能力时,会直接拒绝服务,熔断器不会因为底层旁路应用失效而导致系统雪崩。想要练好这个技能,首先要从请求入口降级,大规模消除过载请求,给系统一些启动预热时间,加载缓存,避免资源死锁背压。被叫方会将其能力反馈给主叫方。.温柔的呼唤需要坚实的沟通。简单来说,只要流量不进系统,什么都可以谈。降级是最强大最霸道的手段;流量一旦进入系统,就必须受到系统中一系列规则的限制。流媒体是阻止请求的最直接方式。虽然用户的请求失败了,但我的系统还活着;没有保险丝的系统是很残忍的,三流功能很容易影响主要功能,所以一定要适时开启;至于热身,就是擦出爱的火花之前的一系列前戏,直到服务的巅峰状态;当然,相对于抛出请求,不管的模式,如果被调用方能够反馈自己的状态,那么请求方就可以根据需要增减马力,这就是背压思想。这些手段都是处理有限资源的有效手段。但如果企业有钱、有弹性去应对,这些就成了辅助手段。毕竟,当所有的服务都能将自己的状态反馈给监控中心时,监控中心就可以实现弹性扩容了。只要服务拆分满足水平扩展,我们只需要增加实例数即可。作者简介:品味小姐姐(xjjdog),一个不允许程序员走弯路的公众号。专注于基础架构和Linux。十年架构,每天百亿流量,与你探讨高并发世界,给你不一样的滋味。
