ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 一、高并发&高可用 其实我们讲过所有的Spring Cloud知识,都为了解决两个问题:一个是高并发,一个是高可用。解决高并发&高可用问题的方法有很多,比如: * 从应用层面:一个好汉三个帮,一个服务实例无法完成的事情,启动多个实例来完成,请求分流负载均衡。 * 从IO模型层面:越来越多的服务框架使用多路选择的异步IO模型,代替阻塞IO模型。 * 从架构层面:主从互备、读写分离等等 * 从算法层面:提高单位请求的运行效率,从而提高并发服务能力 * …… 但是无论你怎么升级硬件、改善架构、改善算法,永远都会有上限,也永远。服务能力就是会存在某一时间段内无法达到高可用的要求,甚至崩溃。 ## 二、服务雪崩 在分布式服务的系统内,很多的用户请求在系统内部都是存在级联式远程调用的。如下图所示:一次请求先后经过Service A、B、C、D,如果此时服务D发生异常,长时间无法响应或者根本不响应,将导致Service C服务调用无法正常响应,进而导致Service B和Service A的响应也出现问题。这种因为服务调用链中某一个服务不可达或超时等异常情况,导致其上游的服务也出现响应异常或者崩溃。当这种情况在高并发环境下就会导致整个系统响应超时、资源等待耗尽,这种现象就是“**服务雪崩**”。 ![](https://img.kancloud.cn/41/e7/41e7a5f575c9dd49d943842836fd5ba1_856x611.png) 当一个服务Service1需要在其方法实现中,调用多个服务提供者时,其中一个服务不可达或者超时的的情况发生,也会导致请求失败。在高并发的环境下,这个问题会更加凸显,也会导致整个微服务系统资源出现等待、无法释放的情况。从而产生服务雪崩。 ![](https://img.kancloud.cn/69/ec/69ec7348a2136f392b8ec236130cd435_855x567.png) **服务重试机制也会产生服务雪崩** 很多朋友在遇到上面的问题时,很自然的想到我们之前为大家讲过的服务请求重试机制(Ribbon和OpenFeign都可以实现服务的请求失败重试)。 * 服务请求重试机制在很大程度上解决了由于网络瞬时不可达的问题,导致服务请求失败的问题。但是在很多的情况下:造成“服务雪崩”的元凶正是“服务重试”机制。 * 某个服务本来就已经出现问题了,造成资源占用无法释放、请求延时等问题。这时在请求失败之后又不断的发送重试请求,在原本就无法释放的资源基础上继续膨胀式占用,导致整个系统资源耗尽。导致服务雪崩。 * 那么是不是我们就应该将“服务重试”配置关闭掉呢?当然也不是,你不能因为马路上发生了车祸,就不让所有人开车。 ## 三、如何解决雪崩的问题之一:服务熔断 > 理解“熔断”这个词的由来,可以帮助我们跟好的理解“熔断”在微服务体系应用的意义。 > > 1. 熔断机制的英文是circuit breaker mechanism,其中circuit breaker在电工学里就是断路器的意思。当电路中出现短路时,断路器会立即断开电路,保护电路负载的安全。 > 2. 后来熔断机制被引入股票交易。最早起源于美国,1987年10月19日,纽约股票市场爆发了史上最大的一次崩盘事件,道琼斯工业指数一天之内重挫508.32点,跌幅达22.6%,由于没有熔断机制和涨跌幅限制,许多百万富翁一夜之间沦为贫民,这一天也被美国金融界称为“黑色星期一”。2020年(今年)由于新冠疫情的影响,美国股市多次触发熔断机制,在一段时间内暂停交易,进而对整个市场起到一定的保护作用。 **服务熔断**:指的是在服务提供者的错误率达到一定的比例之后, 断路器就会熔断一段时间,不再去请求服务提供者,从而避免上游服务被拖垮,进而达到保护整体系统可用性的目的。 **熔断恢复**:熔断时间过了以后再去尝试请求服务提供者,一旦服务提供者的服务能力恢复,请求将继续可以调用服务提供者,此过程完全不需认为参与。 ![](https://img.kancloud.cn/b2/d4/b2d422a0b940fbf9c418e26f049cdde6_794x557.png) 上图是“断路器”的状态转换图 * 断路器默认处于“关闭”状态,当服务提供者的错误率到达阈值,就会触发断路器“开启”。 * 断路器开启后进入熔断时间,到达熔断时间终点后重置熔断时间,进入“半开启”状态 * 在半开启状态下,如果服务提供者的服务能力恢复,则断路器关闭熔断状态。进而进入正常的服务状态。 * 在半开启状态下,如果服务提供者的服务能力未能恢复,则断路器再次触发服务熔断,进入熔断时间。 * * * ## 四、如何解决雪崩的问题之二:服务降级 通过上面的讲解,相信大家已经知道了服务熔断的含义及意义是什么。但是明显遗留了一个问题:服务熔断之后就不在去请求服务调用者原本的方法,那该去请求谁?总不能没有响应吧!这就需要使用到“服务降级”机制了。 白话说服务降级:**服务降级是一种兜底的服务策略,体现了一种“实在不行就怎么这么样”的思想**。想去北京买不到飞机票,实在不行就开车去吧;感冒了想去看病挂不上号,实在不行就先回家吃点药睡一觉吧;实在不行之后的处理方法,被称为fallback方法。 ### 4.1.在服务调用端进行服务降级 ![](https://img.kancloud.cn/e7/57/e757c879bd44da011e92f11d70f28b7d_644x200.png) 当服务提供者故障触发调用者服务的熔断机制,服务调用者就不再调用远程服务方法,而是调用本地的fallback方法。此时你需要预先提供一个处理方法,作为服务降级之后的执行方法,fallback返回值一般是设置的默认值或者来自缓存。 ### 4.2.在服务提供端进行服务降级 除了可以在服务调用端实现服务降级,还可以在服务提供端实现服务降级。实际上在大型的微服务系统中,服务提供者和服务消费者并没有严格的区分,很多的服务既是提供者,也是消费者。 ![](https://img.kancloud.cn/bd/6f/bd6f2e6c318340d1e2e4bee49ddb1a2b_644x285.png) 服务提供者原本的处理请求方法是AMethod(**如运行时异常**),已经不能响应请求,实在不行了就去执行预先定义好的fallback方法。fallback返回值一般是设置的默认值或者来自缓存。 当然,除了服务熔断会触发服务降级和程序运行时异常,还有其他几种异常也可以触发服务降级 * 响应超时 * 达到服务限流标准 * hystrix线程池或信号量爆满 ## 五、服务限流 **服务限流**:通过对并发访问/请求进行限速或者一个时间窗口内的请求数量进行限制来保护系统,一旦达到限制速率则可以拒绝服务。拒绝服务之后,可以有如下的处理方式: * 定向到错误页或告知资源没有了 * 排队或等待(比如秒杀、评论、下单)、 * 降级(返回默认数据或缓存数据)