熔断器/断路器是用来处理重复性故障的一种模式。它保护微服务免受反复调用失败的服务的困扰。断路器是管理交互的三态自动机(图4-4)。它从一个关闭(closed)的状态开始,在这个状态中断路器执行正常的操作。如果交互成功,则什么也不会发生。然而,如果它失败了,断路器会记录下故障。一旦故障数量(在更复杂的情况下可以是故障频率)超过了阈值,断路器就会切换到一个开放(open)状态。在这种状态下,对断路器的调用会立即失败,而不会试图执行与底层的交互。虽然不执行对底层的调用操作,但是断路器可能执行回退(fallback),即提供一个默认的结果。经过配置的一段时间后,断路器认为现在操作有可能会成功,所以它进入半开放(half-open)状态。在这个状态下,对断路器的下一个调用执行底层的交互。根据这个调用的结果,断路器重新设置并返回到关闭(close)状态,或返回到开放(open)状态,直到另一个超时结束。

图4 -4: 断路器状态

Java最知名的断路器实现是Hystrix(https://github.com/Netflix/Hystrix\)。尽管你可以在一个Vert.x微服务中使用Hystrix\(它使用一个线程池\),但是您需要显式地切换到Vert.x的事件回环来执行不同回调。或者,你也可以使用Vert.x为异步操作而构建的断路器,并强制实施Vert.x非阻塞异步开发模型。

让我们想象一个失败的hello microservice。消费者应保护与此服务的交互,并使用断路器如下:

CircuitBreaker circuit = CircuitBreaker.create("my-circuit",
    vertx, new CircuitBreakerOptions()
        .setFallbackOnFailure(true) // Call the fallback
                                    // on failures
        .setTimeout(2000)           // Set the operation timeout
        .setMaxFailures(5)          // Number of failures before
                                    // switching to
                                    // the 'open' state
        .setResetTimeout(5000)      // Time before attempting
                                    // to reset
                                    // the circuit breaker
);
// ...
circuit.rxExecuteCommandWithFallback(
    future ->
        client.get(path)
            .rxSend()
            .map(HttpResponse::bodyAsJsonObject)
            .subscribe(future::complete, future::fail),
    t -> new JsonObject().put("message", "D'oh! Fallback")
).subscribe(
    json -> {
        // Get the actual json or the fallback value
        System.out.println(json.encode());
    }
);

在此代码中,HTTP交互受断路器保护。当故障数量达到配置的阈值时,断路器将停止调用微服务,转而调用一个fallback。周期性地,断路器会让一个调用通过断路器,检查微服务是否回到正轨并相应地采取行动。这个例子使用一个web客户端,但是任何交互都可以通过一个断路器进行管理,并保护您不受不稳定的服务、异常和其他类型的故障的影响。

切换到开放(open )状态的断路器需要由您的运营团队来监控。Hystrix 和Vert.x的断路器都有监控能力。

results matching ""

    No results matching ""