目录
一、基本题目诉求
二、基本分析
(一)概念重申
(二)如何知道一个调用可能会失败?
(三)如何自动恢复?
熔断器状态
恢复机制
三、代码实现
四、开源的熔断器实现
五、总结
干货分享,感谢您的阅读!
在现代分布式系统中,熔断器作为一种关键的容错机制,能有效防止系统由于远程服务的故障而导致的级联崩溃。它通过监控服务调用的健康状况来阻止对故障服务的进一步请求,从而避免系统过载并提高整体稳定性。本篇文章将介绍熔断器的基本概念、自动恢复机制以及如何实现一个简单的熔断器组件。此外,我们还将探讨几种常用的开源熔断器库,以帮助开发者选择适合自己项目的工具。
一、基本题目诉求
/*
实现一个熔断器公共组件, 接入其他服务
implement a circuit breaker common component, used in other services
1. 什么是熔断器?如果我们知道调用可能会失败或超时,则阻止对远程服务的调用。这样做的目的是为了避免不必要的资源浪费同时也降低对远程服务的一些压力
What is a circuit breaker? Block a call to a remote service if we know the call may fail or time out. The purpose of this is to avoid unnecessary waste of resources and reduce some pressure on remote services
2. 如何知道一个调用可能会失败?通过跟踪远程服务发出的请求结果,比如在前面的请求中有m%失败或者超时,则下一次调用也可能会失败
How to know that a call might fail? By tracking the response of the provider. for example, if m% the previous calls failed or timed out, the next call may also fail.
3. 如何自动恢复?如果错误计数超过配置的阈值则熔断器切换为“断开“状态,经过一段配置的时间后,熔断器从断开状态切换到“半开“状态,在这种状态下,它允许一些请求传递到远程服务来检查是否仍然不可用或者缓慢,如果错误率高于配置的阈值则切换回断开状态,否则切换回“关闭”状态以恢复正常操作。
How to recover automatically? If the error count greater than threshold, then change the circuit breaker status to “off”. when the time is greater than the reset threshold, change the circuit breaker status from “off” to “half-open”. it allows some requests to provider to check whether the provider still unavailable, when circuit breaker status is half-open. If the error rate is higher than the threshold, switch back to the off state, otherwise, switch back to the off state to resume normal requests.
*/
二、基本分析
(一)概念重申
熔断器的目的是为了避免不必要的资源浪费,并降低对远程服务的压力。它通过在检测到服务调用可能失败时,阻止进一步的调用,从而防止系统过载。
(二)如何知道一个调用可能会失败?
熔断器通常通过跟踪失败和超时的比例来判断调用是否可能失败。如果失败率或超时率超过了预设的阈值,那么熔断器会认为后续的调用也可能会失败。
(三)如何自动恢复?
熔断器状态
-
OPEN
(打开):熔断器处于这种状态时,所有请求都会被拒绝,直到熔断器自动切换到HALF_OPEN
状态。 -
HALF_OPEN
(半开):熔断器允许部分请求通过来测试服务是否恢复。如果这些请求成功,熔断器会切换回CLOSE
状态;如果失败率仍然很高,它会重新切换回OPEN
状态。 -
CLOSE
(关闭):熔断器正常状态,所有请求都会正常通过,失败计数会被重置。
恢复机制
- 如果错误计数超过了阈值,熔断器会进入
OPEN
状态。 - 在
OPEN
状态下,熔断器会等待一段配置的时间(称为“重置超时”),然后尝试切换到HALF_OPEN
状态。 - 在
HALF_OPEN
状态下,熔断器会允许少量请求通过,以检测服务的健康状态。如果这些请求中的错误率低于阈值,熔断器会切换回CLOSE
状态;否则,会重新进入OPEN
状态。
三、代码实现
实现一个基本的熔断器逻辑,通过状态管理和自动恢复机制来防止对远程服务的过度调用,使用同步机制来确保线程安全,并提供一个简单的模拟远程服务的测试环境。虽然这个实现能够演示熔断器的基本概念,但在实际应用中可能需要更多的功能和优化,比如更复杂的状态管理、动态配置和性能优化。
package ;
import ;
import ;
import ;
import ;
/**
* @program: zyfboot-javabasic
* @description: 实现一个熔断器公共组件接入其他服务?
* @author: zhangyanfeng
* @create: 2024-09-11 18:50
**/
public class CircuitBreaker {
private enum State {
CLOSE, HALF_OPEN, OPEN
}
private State state = ;
private final int failureThreshold;
private final long resetTimeout; // in milliseconds
private final AtomicInteger failureCount = new AtomicInteger(0);
private LocalDateTime lastFailureTime;
public CircuitBreaker(int failureThreshold, long resetTimeout) {
= failureThreshold;
= resetTimeout;
}
public <T> T execute(Supplier<T> businessLogic, Supplier<T> fallback) {
synchronized (this) {
if (state == ) {
if (canReset()) {
state = State.HALF_OPEN;
} else {
("熔断器打开,拒绝请求!");
return ();
}
}
}
try {
T result = ();
synchronized (this) {
reset();
}
return result;
} catch (Exception e) {
synchronized (this) {
();
lastFailureTime = ();
if (() >= failureThreshold) {
state = ;
("熔断器打开!");
return ();
}
}
throw e; // rethrow the exception if it doesn't meet the threshold
}
}
public boolean callService(RemoteService service) {
synchronized (this) {
if (state == ) {
if (canReset()) {
state = State.HALF_OPEN;
} else {
("熔断器打开,拒绝请求!");
return false;
}
}
}
boolean success = ();
synchronized (this) {
if (success) {
reset();
return true;
} else {
();
lastFailureTime = ();
if (() >= failureThreshold) {
state = ;
("熔断器打开!");
return false;
}
}
}
return success;
}
private synchronized void reset() {
state = ;
(0);
lastFailureTime = null;
("熔断器重置为CLOSE状态!");
}
private synchronized boolean canReset() {
if (lastFailureTime == null) {
return false;
}
long timeSinceLastFailure = (lastFailureTime, ());
return timeSinceLastFailure >= resetTimeout;
}
public static class RemoteService {
public boolean call() {
// 模拟服务调用
return () > 0.5;
}
}
public static void main(String[] args) throws InterruptedException {
// 失败阈值为3,重置时间为5s
CircuitBreaker breaker = new CircuitBreaker(3, 5000);
RemoteService service = new RemoteService();
// 模拟多次调用服务
for (int i = 0; i < 10; i++) {
("第" + (i + 1) + "次请求:");
(service);
// 每次调用间隔1s
(1000);
}
}
}
运行结果体会如下:
第1次请求:
第2次请求:
熔断器重置为CLOSE状态!
第3次请求:
熔断器重置为CLOSE状态!
第4次请求:
熔断器重置为CLOSE状态!
第5次请求:
第6次请求:
第7次请求:
熔断器重置为CLOSE状态!
第8次请求:
第9次请求:
第10次请求:
熔断器重置为CLOSE状态!
四、开源的熔断器实现
在实际开发中,熔断器通常作为微服务架构中的重要组件来使用,主要有以下几种开源的熔断器实现:
库/工具 | 简介 | 主要功能 | 适用性 | 官网 |
---|---|---|---|---|
Hystrix | Netflix 开发的熔断器库 | 熔断器功能、延迟和超时控制、线程池和信号量隔离、回退机制、监控 | Java | Hystrix GitHub |
Resilience4j | 轻量级熔断器库,现代化实现 | 熔断器功能、限流器、重试机制、超时控制、事件发布和监控 | Java 8 及以上 | Resilience4j GitHub |
Spring Cloud Circuit Breaker | Spring Cloud 集成熔断器支持 | 提供统一 API,支持 Hystrix、Resilience4j、Sentinel 等 | Spring Cloud 框架 | Spring Cloud Circuit Breaker GitHub |
Sentinel | Alibaba 开发的熔断器和流量控制工具 | 熔断器功能、流量控制、热点参数限流、监控和统计 | Java 和其他语言 | Sentinel GitHub |
Polly | .NET 的弹性和转移库 | 熔断器功能、重试机制、超时控制、限流控制 | .NET 环境 | Polly GitHub |
Tyk | API 网关,包含熔断器功能 | 熔断器功能、流量控制、监控和日志 | API 网关场景 | Tyk GitHub |
这些开源熔断器组件可以根据不同的需求和技术栈选择合适的实现。它们通常提供了熔断器功能的基础实现,并结合了其他功能如限流、重试、超时等,以增强系统的鲁棒性。
五、总结
熔断器是一种用于防止服务故障引发系统崩溃的机制。本文首先回顾了熔断器的基本概念及其工作原理,介绍了如何通过监控失败率来判断调用是否可能失败,以及熔断器如何在服务恢复时自动切换状态。接着,提供了一个 Java 实现的基本熔断器代码示例,展示了熔断器如何管理状态并处理服务调用。最后,文章列出了几种流行的开源熔断器库,包括 Hystrix、Resilience4j、Spring Cloud Circuit Breaker、Sentinel、Polly 和 Tyk,详细介绍了它们的主要功能和适用场景,帮助开发者选择合适的熔断器解决方案。