# 15.1 了解断路器

在《发布！软件的设计与部署》一书的第二版，Michael Nygard 阐述了这样的事实：就是我们编写的代码总会出错。断路器模式很有用，主要的原因是，当代码运行失败时，它会优雅地失败。这种强大的模式在微服务环境中更为重要，因为它可以避免故障级联跨越到分布式调用的整个链路中。

断路器模式的概念相对简单，这非常类似一个真实世界的电子断路器，它的名字也来源于此。在带有断路器的电路中，当开关处于闭合位置时，电流流动，给灯、电视、电脑等电器供电。但是如果线路有任何异常，比如电涌，断路器会断开，在电流损坏电子设备或引起火灾之前停止电流流动。

同样，软件断路器在闭合状态下启动，允许调用方法。如果由于一些原因，该方法失败（可能超过定义的阈值），断路器断开，不再对故障方法执行调用。然而，软件断路器的不同之处在于，它还提供了降级行为和自我纠正能力。

如果受保护的方法失败次数达到给定的失败阈值，则可以调用降级方法。一旦断路器断开，请求就全部调用降级方法。然而，每隔一段时间，调用链路就会进入半开状态，并尝试调用失败的方法。如果仍然失败，将恢复断开状态。如果成功了，那么就假定问题已经解决了。回到闭合状态。图 15.1 说明了软件断路器的状态变化流程。

![](https://867170852-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LrmLE3NwQoVJk02Q_BX%2F-MgLpwMgYlB7MCNy0f4h%2F-MgLq3uOuNgmRUzCyiPi%2F15.1.png?alt=media\&token=f10dad9e-7a19-418d-b2b3-01738c319835)

把断路器模式看作是一种更强大的 `try/catch`，会有助于您理解。闭合电路类似于 `try` 代码块，而降级方法类似于 `catch` 代码块。然而，与 `try/catch` 不同，断路器足够智能，在预期的方法失败得太频繁时，会绕过预期方法而调用降级方法。

正如我所暗示的，断路器应用于方法上。微服务内很容易有几个或十几个（或更多）的断路器。决定在哪里的代码中声明断路器，是一个先要识别出哪里的方法可能失败的问题。以下几种方法是使用断路器的典型方法：

* 进行 REST 调用的方法——这种方法可能会失败，因为远程服务可能不可用或返回 HTTP 500 响应。
* 执行数据库查询的方法——这种方法可能会失败，因为一些原因数据库可能无响应，或者表结构变化使用应用程序报错。
* 执行速度慢的方法——执行慢也不一定就失败，但如果执行时间太长的话，可以认为是不正常的。

最后一项强调了断路器除了处理故障之外的另一个好处。在微服务中，延迟也是一个重要的关注点。关键是要使慢方法不要拖累微服务的性能，导致上游服务产生级联延迟。

正如你所见，断路器模式用一个难以置信的强大手段，优雅地处理代码中的失败和延迟。我们怎样才能把断路器用在我们的代码中呢？幸运的是，Netflix 开源项目提供了 Hystrix 库。

Netflix Hystrix 是断路器模式的 Java 实现。简单地说，Hystrix 断路器被实现为应用在方法上一个切面：如果目标方法失败，则触发降级方法。为正确实施断路器模式，切面还跟踪目标方法的失败频率，如果失败率超过一些阈值，是触发降级方法。

&#x20;**HYSTRIX 名称的来历**

Netflix 的开发人员在为他们的断路器实现命名时，他们希望有一个能体现弹性、防御和容错能力的名字。他们选择了 `Hystrix`。这是一种能用长棘刺自卫的，生活在东半球的豪猪。另外，正如 Hystrix 常见问题解答中所解释的，这名称听起来很酷。当我们在第 15.3.1 节查看 Hystrix 仪表板时，您将看到项目标志是一只豪猪。

Spring Cloud Netflix 包含了对 Hystrix 的支持，提供了 Spring 和 Spring Boot 开发人员都熟悉的简单编程模型。在方法上声明断路器只需用 @HystrixCommand 注解，并提供了一个降级方法。让我们看看在 Taco Cloud 的代码中，如何使用 Hystrix 断路器优雅地处理失败。
