熔断
A服务的X功能依赖B服务的某个接口,当B服务接口响应很慢时,A服务X功能的响应也会被拖慢,进一步导致了A服务的线程都卡在了X功能上,A服务的其它功能也会卡主或拖慢。此时就需要熔断机制,即A服务不在请求B这个接口,而可以直接进行降级处理。
状态机的三个状态
Closed: 关闭状态(断路器关闭),所有请求都正常访问。
Open: 打开状态(断路器打开),所有请求都会被降级。Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全关闭。默认失败比例的阈值是50%,请求次数最少不低于20次。
Half Open: 半开状态,Closed状态不是永久的,关闭后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会完全打开断路器,否则继续保持关闭,再次进行休眠计时。
案例
ConsumerController添加熔断机制 @HystrixCommand
@RestController
@RequestMapping("consumer")
@DefaultProperties(defaultFallback = "queryByIdFallback")//全局开启失败容错(所有方法都用)
public class ConsumerController {
@Autowired
private RestTemplate template;
@GetMapping("{id}")
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), //触发熔断最小请求此书,默认为20
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), //休眠时长,默认是5000毫秒
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60") //触发熔断的失败请求最小占比,默认为50%
})
public String queryById(@PathVariable("id") int id) {
if (id % 2 == 0){
throw new RuntimeException(""); //抛出异常会触发熔断
}
String url = "http://user-service/user/" + id;
String user = template.getForObject(url, String.class);
return user;
}
public String queryByIdFallback() {
return "服务器正忙,请稍后再试!";
}
}
查找配置熔断信息的key值
验证
在ConsumerController有判断条件,如果输入查询id为偶数则会抛出异常触发熔断
1.输入id为1不会抛出异常,即不会发生熔断,查询结果正常
2. 输入id为2,会抛出异常,查询失败
3.多次切访问id为2地址,会因为多次异常产生服务熔断且使得服务休眠,再次访问id为1地址,会查询失败
4.触发熔断,该服务暂时失效
5。等待一定时间后,熔断关闭,可id为1的情况可正常访问