Hystrix通过隔离服务之间的访问点,阻止它们之间的级联故障,并提供回退选项,所有这些都提高了你系统的整体弹性。
解决灾难雪崩效应和故障影响
- 降级:超时降级,资源不足时(线程和信号量)降级,降级后可以配置降级接口返回托底数据。实现一个fallback方法,当请求后端服务出现异常的时候,可以使用fallback方法返回值。
- 熔断:当失败率,(因网络故障,超时造成的失败率高)达到阈值自动触发降级,熔断器触发的快速失败会进行快速恢复。默认是开启的。(某个服务出现容错率在10s超过50%,自动启动熔断)
提示服务的并发能力,就是一种避免雪崩现象解决方案: - 线程隔离:限制调用分布式服务的资源使用,某一个掉用的服务出现问题不会影响其他服务调用。
- 请求缓存:提供请求缓存
- 请求合并:提供请求合并
- 信号量隔离
Hystrix解决方案-服务降级
在开发中服务和服务直接调用关系,调用过程服务肯定会出现如下问题:
- 调用者(消费者):自身服务程序出现异常和故障就会走入fallback
- 提供者:(生产者):调用服务过程中出现:读超时的情况或者连接超时的情况,也会进入fallback
fallback: 就是指容错降级,也称之为:出现故障和异常的一种兜底方案。默认情况下是:开启。
触发条件
有一种情况下不会:出现HystrixBadRequestException异常的时候。
以下四种情况会触发:
- 1、方法抛出非HystrixBadRequestException异常
- 2、方法调用超时
- 3、熔断器开启拦截调用
- 4、线程池、队列、信号量是否饱满。
默认的容错降级DefaultFallback
package com.clound.controller;
import com.clound.pojo.SysUser;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/consumer")
@DefaultProperties(defaultFallback = "defaultFallback")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/user/{id}")
@HystrixCommand
public SysUser getUser(@PathVariable("id") Long id) {
// 1、调用者(消费者):自身服务程序出现异常和故障就会走入fallback
if (id == 1L) {
throw new RuntimeException();
}
String url = "http://hystrix-user-service/user/" + id;
return restTemplate.getForObject(url, SysUser.class);//
}
public SysUser defaultFallback() {
return new SysUser();
}
}