0 作用
Hystrix是一个延迟和容错库,用于隔离访问远程服务,防止出现级联失败
1 雪崩
微服务中,服务间调用关系错综复杂,一个请求,可能需要调用多个微服务接口才能实现,会形成非常复杂的调用链.一次业务请求,需要调用A、P、H、I四个服务,这四个服务又可能调用其它服务.如果此时,某个服务出现异常:例 微服务I 发生异常,请求阻塞,用户请求就不会得到响应,则tomcat的这个线程不会释放,于是越来越多的用户请求到来,越来越多的线程会阻塞.服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致所有其它服务都不可用,形成雪崩效应.
雪崩-0
雪崩-1
2 hystrix解决雪崩方案
- 线程隔离:用户请求不直接访问服务,而是使用线程池中空闲的线程访问服务,加速失败判断时间。
- 服务降级:及时返回服务调用失败的结果,让线程不因为等待服务而阻塞
3 hystrix使用
- 依赖
<!-- 消费者中增加依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 启动类上加注解@EnableCircuitBreaker
//@SpringBootApplication
//@EnableDiscoveryClient
//@EnableCircuitBreaker
@SpringCloudApplication //该注解可代替以上三个注解
public class HelloConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(HelloConsumerApplication.class,args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 定义降级逻辑方法,要与原方法参数返回值一致
- 在原方法上增加@HystrixCommand(fallbackMethod = "降级方法名称")
@RestController
@RequestMapping("/test-hystrix")
@DefaultProperties(defaultFallback = "defaultCallBack") // 也可以给整个类都定义上统一的降级方法,默认方法返回类型必须与调用方法一致,并且不能有参数,然后在类上指定降级方法名称@DefaultProperties,在方法上加@HystrixCommand
public class TestHystrixController {
@Autowired
private RestTemplate restTemplate;
@GetMapping
@HystrixCommand(fallbackMethod = "getHystrixCallBack") // 使用熔断注解定义降级方法,远程调用失败后会回调降级方法
public String getHystrix(){
String serviceId = "http://hello-service";
String str = restTemplate.getForObject(serviceId + "/service/hystrix", String.class);
return str;
}
/**
* 降级逻辑方法,注意需与原始方法参数、返回值一致
* @return
*/
public String getHystrixCallBack(){
String nowTime = LocalDateTime.now().toString();
return nowTime + " 服务暂不可用";
}
/**
* 默认降级方法,默认方法返回类型必须与调用方法一致,并且不能有参数
* @return
*/
public String defaultCallBack(){
String nowTime = LocalDateTime.now().toString();
return nowTime + " 默认服务暂不可用";
}
}
- 超时配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 # 默认为1s
4 服务熔断
- 熔断机制
Hystrix的服务熔断机制,可以实现弹性容错;当服务请求情况好转之后,可以自动重连。通过断路的方式,将后续请求直接拒绝,一段时间(默认5秒)之后允许部分请求通过,如果调用成功则回到断路器关闭状态,否则继续打开,拒绝请求的服务。 -
图解
熔断机制.png - 实例
/**
* 参数为1时肯定会失败,等一定时间内次数过多会触发熔断,即便参数正确也会执行降级方法,直到休眠时间过后正确参数就会访问成功
* @param id
* @return
*/
@GetMapping("/test-cercuit-breaker/{id}")
@HystrixCommand
public String testCercuitBreaker(@PathVariable Integer id){
if (id == 1){
throw new RuntimeException("访问失败");
}else {
return "访问成功";
}
}
操作:参数为1连续访问20次,都会返回降级方法返回值,这时在将参数改为2,仍然会服务降级,等5s后,使用参数2就会访问成功
- 熔断器参数配置
# hystrix在idea中没有提示
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 #超时配置
circuitBreaker:
errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%
sleepWindowInMilliseconds: 10000 # 熔断后休眠时长,默认值5秒
requestVolumeThreshold: 10 # 熔断触发最小请求次数,默认值是20