## 熔断原理

熔断器,页脚断路器,其英文单词为:Circuit Breaker.

熔断机制的原理很简单,像家里的电路熔断器,如果电路发生短路能立刻熔断电路,避免发生火灾.在分布式系统中应用这一模式之后,服务调用方可以自己进行判断某些服务反应慢或者存在大量超时的情况时,能够主动熔断,防止整个系统被拖垮.

不同于电路熔断只能断不能自动重连,Hystrix可以实现弹性容错,当情况好转之后,可以自动重连.这就好比魔术师把鸽子变没了容易,但是真正考验技术的是如何把小时的鸽子再变回来.

通过断路的方式,可以将后续请求直接拒绝掉,一段时间之后允许部分请求通过,如果调用成功则回到电路闭合状态,否则继续断开.

![](https://box.kancloud.cn/666092668a29caa8cb6422f98bbecdfb_827x486.png)

## 状态机三种状态

1. Closed:关闭状态(断路器关闭),所有请求都正常访问.

2. Open:打开状态(断路器打开),所有请求都会被降级.Hystrix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全关闭.默认失败比例的阈值是50%,请求次数最少不低于20次.

3. Half Open:半开状态,Closed状态不是永久的,关闭后会进入休眠时间(默认是5S).随后断路器会自动进入半开状态.此时会释放部分请求通过,若这些请求都是健康的,则会完全关闭断路器,否则继续保持打开,再次进行休眠计划.

## 配置
circuitBreaker.requestVolumeThreshold:触发熔断的最小请求次数,默认20.
circuitBreaker.sleepWindowInMilliseconds:休眠时长,默认是5000毫秒.
circuitBreaker.errorThresholdPercentage:触发熔断的失败请求最小占比,默认50%.
## 代码
~~~
@RestController
@RequestMapping("/user")
@DefaultProperties(defaultFallback = "defaultCallBack")
public class UserController
{
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/{id}")
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //最近请求的次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠时间
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") //错误百分比
})
public String index(@PathVariable("id") Long id)
{
if (id % 2 == 0) {
throw new RuntimeException(""); //模拟请求失败
}
String url = "http://user-server/user/";
return restTemplate.getForObject(url + id, String.class);
}
public String defaultCallBack()
{
return "服务器压力很大";
}
}

~~~

### 快速请求几次,触发熔断器:

![](https://box.kancloud.cn/2d3d3f91ef11b11e11e38999f51d612f_1090x696.png)

### 当我们再次请求正常逻辑之后,会快速失败:

![](https://box.kancloud.cn/f4d1a60f19b692c3b40f8b0fc71272fe_1174x726.png)