图3.2 极端情况下的微服务网状调用示意图
最常见的场景就是当负载过高时,如果某个服务的性能或抗压能力不好,那么当请求到这个服务时就需要等待或直接出现超时、不可用等情况。在图3.2中,一旦服务C出现问题,可能会影响服务A和服务B,虽然服务D、E、F并没有直接与服务C相互依赖,但是服务C导致了服务A和服务B的阻塞,就会间接地影响服务D、E、F,从而让整个系统变得缓慢或不可用,这就是微服务的雪崩效应。
微服务调用都以远程调用为主,内存中调用和远程调用之间的一个重大区别是远程调用可能会失败,或者在达到某个超时限制之前挂起而没有响应。如果在没有响应的供应商上有许多呼叫者,那么更糟糕的是,你可能会耗尽关键资源,导致跨多个系统的级联故障。这些问题还是很容易发生的,那么应该如何避免呢?其实要避免雪崩效应,根本的问题就是如何让单个有问题的服务不去影响其他服务的正常运行,这样就能将“雪崩”的范围控制到最小,从而不会将问题的影响蔓延至整个系统。
断路器(Circuit Breaker)就是为了解决这个问题而产生的。那么什么是断路器呢?听起来就像日常生活中的保险丝或空气开关一样,很多高功率的电器、家中和生产场所中都会有电路的保险装置,这些装置一般称为断路器,断路器会在短路和严重超载的情况下切断电路,从而有效地保护回路中的电器,防止电器损坏和火灾的情况发生。
技术有很多时候的设计往往都源于生活,微服务中的断路器其实就是效仿真实生活中的断路器,当服务过载而导致响应过慢或不可用时,断路器能及时地切断真实的服务调用,并返回提前设定好的响应,保证调用方其他功能的正常运行。
那么,如何实现一个断路器呢?你可以自己去实现一个断路器,首先需要在服务调用方监控服务的调用情况,然后设置一些阈值,如响应时间不得超过15s、错误次数比例不得超过30%等,再去定义一些调用失败后预期的返回结果,如查询一个员工的姓名,返回张三,当调用结果情况超过了设定的阈值时,断路器就改变服务的调用策略,消费者将不再调用原来的服务,当请求发起时,直接返回之前设置的另一个调用策略,通常称这种方式为服务降级策略,这样就可以实现一个断路器的基本功能了。
下面来了解一下Spring Cloud系列的断路器:Spring Cloud Netflix Hystrix是如何使用的。Spring Cloud Netflix Hystrix是Spring Cloud关于解决微服务雪崩效应的解决方案,不过看名称可以知道,Hystrix仍然是由大名鼎鼎的Netflix开发并开源的产品,Spring Cloud很好地对它进行了封装,并且与Spring Cloud Ribbon、Spring Cloud Feign等框架可以无缝集成。
Spring Cloud Netflix Hystrix提供了断路器的全部功能,首先需要在服务调用端引入Hystrixstarter:
spring-cloud-starter-netflix-hystrix,配置如下。