使用Hystrix实现微服务的容错处理
1.实现容错的手段
如果服务提供者响应的速度特别慢,那么消费者对提供者的请求就会强制等待,直到提供者响应或者超时。在高负载的情况下,如果不做任何处理,此类问题可能会导致服务消费者的资源耗尽甚至整个系统的崩溃。例如曾经发生的一个案例,某个电子商务网站在某个星期五发生过载,过多的并法请求,导致用户支付请求延迟很久没有响应,在等待很长时间后最终失败,支付失败又导致用户重新刷新页面再次尝试支付,进一步增加了服务器的负载,最终整个系统崩溃了。
1.1雪崩效应
我们常把基础服务故障导致级联服务故障的现象称为雪崩效应。雪崩效应描述的是提供方不可用导致消费方不可用并将不可用逐渐放大的过程。
如下,当请求一直得不到回应,并且新的请求不断涌入,导致了雪崩效应
1.2.如何容错
想要避免雪崩效应,必须有强大的容错机制,该容错机制需要实现以下两点
-
为网络请求设置超时
-
使用断路器模式
正常情况下断路器关闭可正常请求服务,当一定时间内请求达到了一定的阈(yu)值(错误率达到百分之50或者100次/分钟),断路器就会打开此时不会再去请求依赖服务,断路器打开一段时间之后,会自动进入半开的状态。此时断路器允许一个请求请求服务实例,如果该服务可以调用成功,则关闭断路器,否则继续保持打开状态。
断路器Hystrix应该在哪一方使用?
断路器应该在消费者一方使用,这样才能生效,如果设置在服务者一方,请求已经到达服务者,无法保护消费者和服务者。
2.使用hystrix实现容错
hystrix是Netfilx开源的延迟和容错库,用于隔离访问远程系统,服务或者第三方库,防止级联失败,从而提升系统的可用性和容错性
3.通用方式整合Hystrix
1.为项目添加依赖
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2.在消费者的入口类上添加注解
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class HiApplication {
public static void main(String[] args) {
SpringApplication.run(HiApplication.class, args);
}
3.让当前方法具备容错的能力
使用注解:@HystrixCommand(fallbackMethod = "hystrixFallback") ,并指定当断路器生效时调用的方法。
@RestController
@RequestMapping("/query")
public class ClientController {
@Autowired
private RestTemplate restTemplate;
@Autowired
LoadBalancerClient loadBalancerClient;
@HystrixCommand(fallbackMethod = "hystrixFallback")
@RequestMapping("/test")
public String test(String name){
String template = restTemplate.getForObject("http://EUREKA-PROVIDER/test/test1?name=" + name, String.class);
return template;
}
//断路器生效时调用的方法
public String hystrixFallback(String name){
return "hystrixFallback info "+name;
}
}
4.测试
1.启动eureka服务
2.启动生产者
3.启动消费者
4.访问消费者 http://localhost:8762/query/test?name=haha
结果
xixixi 8763 :haha
5.关闭生产者
6.访问消费者
结果
hystrixFallback info haha
我们知道,当请求失败,被拒绝超时或者短路器打开时都会进入到回退方法,但是进入回退方法并不是意味着断路器被打开,那怎样才算断路器打开呢?
5.实验 进行健康监测实时查看断路器是否打开
1.启动eureka服务
2.启动生产者
3.启动消费者
4.访问消费者
结果
{"name":"xiaohei","password":null,"age":null}
5.访问 http://ip:port/health
{
status:"up",
hystrix:{
status:"up"
}
}
6.关闭生产者
7.访问消费者
结果
{"name":"xiaohei","password":null,"age":-1}
8.访问 http://ip:port/health
{
status:"up",
hystrix:{
status:"up"
}
}
通过这里我们可以发现,尽管执行了fallback方法,但此时hystrix状态依然是up,这是因为咱们的失败率还没有达到阀值(默认5秒20次失败),这里再次强调,执行回退的逻辑并不代表断路器已经打开,请求超时,失败,被拒绝以及断路器打开都会执行回退逻辑
9.5秒请求20次
{
status:"up",
hystrix:{
status:"CIRCUIT_OPEN"(断路器打开的标识)
}
}
断路器的状态
半开状态
正常运行
开启状态
4.feign整合Hystrix
很显然@HystrixCommand是添加到方法上的,那么对于feign来说一定不适用,如何让Hystrix整合feign?
1.feign方法上添加相关注解
@FeignClient(serviceId = "HI-SERVICE",fallback = FeignClientFallBack.class)
public interface feignPost {
@RequestMapping(value = "/test/test1", method = RequestMethod.POST)
public User sayHi(User user);
}
2.实现Feign接口
@Component //将该类交由工厂管理
public class FeignClientFallBack implements feignPost {
@Override
public User sayHi(User user) {
System.out.println("Hystrix method is invoke");
return null;
}
}
3.添加feign的配置文件
为feign开启断路器
feign.hystrix.enabled=true