13. 熔断机制: Hystrix 客户端

Netflix 创建了一个名为 Hystrix 的库,用于实现熔断机制模式。在微服务架构中,通常有多个服务调用层,如下例所示:

图 13.1. 微服务图

Hystrix

较低级别的服务中的服务失败可能会导致级联失败,直至用户为止。当对特定服务的调用超过 circuitBreaker.requestVolumeThreshold(默认值:20 个请求),并且在由 metrics.rollingStats.timeInMilliseconds(默认值:10 秒)定义的滚动窗口中失败百分比大于 circuitBreaker.errorThresholdPercentage(默认值:50%)时,熔断,不进行调用。在出现错误和开路的情况下,开发人员可以提供回退。

图 13.2. Hystrix 回退防止级联故障

HystrixFallback

有一个开路停止级联故障,并允许不知所措或失败的服务时间恢复。回退可以是另一个受 Hystrix 保护的调用、静态数据或显式空值。回退可以链接起来,以便第一个回退进行其他业务调用,而这反过来又返回到静态数据。

13.1 如何包含 Hystrix

要在项目中包含 Hystrix,请使用 group ID 为 org.springframework.cloud 和 artifact ID 为 spring-cloud-starter-netflix-hystrix 的 starter。请参见 Spring Cloud 项目页面,了解有关使用当前 Spring Cloud Release Train 构建系统设置的详细信息。

以下示例展示了带有 Hystrix 熔断机制的最小 Eureka 服务器:

@SpringBootApplication
@EnableCircuitBreaker
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}

@Component
public class StoreIntegration {

    @HystrixCommand(fallbackMethod = "defaultStores")
    public Object getStores(Map<String, Object> parameters) {
        //do stuff that might fail
    }

    public Object defaultStores(Map<String, Object> parameters) {
        return /* something useful */;
    }
}

@HystrixCommand 由名为 “javanica” 的 Netflix contrib 库提供。Spring Cloud 会自动将带有该注解的 Spring Beans 包装在连接到 Hystrix 断路器的代理中。断路器计算何时打开和关闭电路,以及发生故障时应采取的措施。

要配置 @HystrixCommand,可以使用带有 @HystrixProperty 注解列表的 commandProperties 属性。有关详细信息,请参阅此处。有关可用属性的详细信息,请参阅 hystrix wiki。

13.2 传播安全上下文或使用 Spring 范围

如果希望一些线程本地上下文传播到 @HystrixCommand 中,则默认声明不起作用,因为它在线程池中执行命令(在超时的情况下)。你可以通过配置或直接在注解中切换 Hystrix 使用与调用者相同的线程,方法是要求它使用不同的“隔离策略”。下面的示例演示如何在注解中设置线程:

@HystrixCommand(fallbackMethod = "stubMyService",
    commandProperties = {
      @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
    }
)
...

如果你使用的是 @SessionScope 或 @RequestScope,则同样适用。如果遇到运行时异常,说明它找不到作用域上下文,则需要使用相同的线程。

你还可以选择将 hystrix.shareSecurityContext 属性设置为 true。这样做会自动配置一个 Hystrix 并发策略插件挂钩,将 SecurityContext 从主线程传输到 Hystrix 命令使用的线程。Hystrix 不允许注册多个 Hystrix 并发策略,因此可以通过将自己的 HystrixConcurrencyStrategy 声明为 Spring Bean 来使用扩展机制。Spring Cloud 在 Spring 上下文中查找你的实现,并将其包装在自己的插件中。

13.3 健康指标

连接的断路器的状态也暴露在调用应用程序的 /health 端点中,如以下示例所示:

{
    "hystrix": {
        "openCircuitBreakers": [
            "StoreIntegration::getStoresByLocationLink"
        ],
        "status": "CIRCUIT_OPEN"
    },
    "status": "UP"
}

13.4 Hystrix 流计量

要启用 Hystrix 流计量,请包含对 spring-boot-starter-actuator 的依赖,并设置 management.endpoints.web.exposure.include: hystrix.stream。这样做会将 /actuator/hystrix.stream 作为管理端点公开,如下例所示:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>