Spring Cloud Hystrix(一)

202 阅读3分钟

1,Hystrix的作用

  • 1)对通过第三方客户端访问的依赖项(通常是通过网络)的延迟和故障进行保护和控制。
  • 2)在复杂的分布式系统中阻止级联故障。
  • 3)快速失败,快速恢复。
  • 4)回退,尽可能优雅的降级。
  • 5)启用近实时监控,警报和操作控制。

2,项目配置及代码实现

1),user-service-provider的pom.xml文件中增加配置

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

代码部分 首先贴一下服务提供方的代码,注意这种写法!

public interface OrderService { //在order-service-api中

    @GetMapping("/orders")
    String orders();

}

@RestController
public class OrderServiceImpl implements OrderService { //在order-service-provider中

    @Value("${server.port}")
    private String serverPort;

    @Override
    public String orders() {
        try {
            Thread.sleep(3100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("请求进来啦..port:" + serverPort);
        return "This is xiaofeng's all orders";
    }

}

2.1 熔断触发降级场景

1,启动类增加@EnableCircuitBreaker
@EnableCircuitBreaker
@SpringBootApplication
public class UserServiceProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceProviderApplication.class, args);
    }

}
2,测试类
@RestController
public class HystrixController {

    @Autowired
    RestTemplate restTemplate;

    /**
     *  【熔断触发降级场景】
     * 10秒之内,发起至少5次请求,然后有至少50%的错误率,就会熔断5s
     *
     * 【注释:如果不配置,默认是:10s钟之内,发起了20次请求,失败率超过50%。
     *              熔断的恢复时间(熔断5s),从熔断开启 到后续5s之内的请求,都不会发起到远程服务端】.
     *
     * 所有的属性都在HystrixCommandProperties中
     * @param num
     * @return
     */
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name="circuitBreaker.enabled",value ="true"), //开启状态
            @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "5"), //最小请求次数
            @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000"), //5s 熔断时间
            @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50") //异常率大于等于50%
    },fallbackMethod = "fallback")
    @GetMapping("/hystrix/order/{num}")
    public String queryOrder(@PathVariable("num") int num){
        if(num % 2 == 0){
            return "正常访问";
        }
        //测试的时候order-server服务先不要启动.
        return restTemplate.getForObject("http://localhost:8082/orders",String.class);
    }

    public String fallback(int num){ //回退的方法的参数完全一致,才会调用
        //返回兜底数据
        return "系统繁忙,请稍后再试~";
    }

}

然后不断的刷新http://localhost:8081/hystrix/order/1,然后发现请求http://localhost:8081/hystrix/order/2 也出现了异常,如下: 然后过了几秒,请求http://localhost:8081/hystrix/order/2又恢复了正常(熔断有一个自动恢复)。如下:

2.2 超时触发降级场景

2.2.1 普通写法
  /**
   * 【超时触发降级】
   * @return
   */
  @HystrixCommand(commandProperties = {
          @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000")
  },fallbackMethod = "timeoutFallBack")
  @GetMapping("/hystrix/timeout")
  public String queryOrderTimeout(){
      /**
       * 经测试,这里的超时是真正的超时,不是服务不可用,
       *  意思是如果http://localhost:8082/orders调不通,那么会立即返回 请求超时,不会等待3s,
       *      如果是http://localhost:8082/orders的逻辑中处理时长超过3s,才会真正的去等待3s,超过3s后才会出现 请求超时.
       */
      return restTemplate.getForObject("http://localhost:8082/orders",String.class);

  }

  public String timeoutFallBack(){
      return "请求超时";
  }

注意下默认情况,默认是1s就会超时

    @HystrixCommand(fallbackMethod = "timeoutFallBack")
    @GetMapping("/hystrix/timeout")
    public String queryOrderTimeout(){...}

2.2.2 OpenFeign超时降级

下面这个包是feign和hystrix的集成 服务提供方(order-service-api)

@FeignClient(value = "order-service",fallback = OrderServiceFeignClient.OrderServiceFeignClientFallBACK.class)
public interface OrderServiceFeignClient extends OrderService {

    @Component
    class OrderServiceFeignClientFallBACK implements OrderServiceFeignClient{
        @Override
        public String orders() {
            return "查询订单失败,请稍后再试~";
        }
    }

}

服务调用方 (user-service-provider)

1,写调用类
@RestController
public class HystrixFeignController {

    @Autowired
    OrderServiceFeignClient orderServiceFeignClient;

    @GetMapping("/hystrix/feign/order")
    public String queryOrder(){
        return orderServiceFeignClient.orders();
    }

}

2,在启动类上增加@EnableFeignClients(basePackages = "com.xiaofeng.myorder.cn.clients")
@EnableCircuitBreaker
@ComponentScan(basePackages = {
        "com.xiaofeng.myorder.cn.clients",
        "com.xiaofeng.cn"
})
@SpringBootApplication
@EnableFeignClients(basePackages = "com.xiaofeng.myorder.cn.clients")
public class UserServiceProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceProviderApplication.class, args);
    }

}

application.yml配置新增:

# 开启feign hystrix的支持,这边打开,才会触发降级的策略
feign:
  hystrix:
    enabled: true
# 配置hystrix超时时间,不能配置在注解上面,注意feign调用的时候其实ribbon本身也有超时时间,和hystrix一起就是有两个超时时间了
hystrix:
  command:
    default:  #全局配置, feignclient#method(param)
      execution:
        timeout:
          enable: true
        isolation:
          thread:
            timeoutInMilliseconds: 3000
ribbon:  #ribbon的时间一定要大于hystrix的时间,这样才会让hystrix的超时时间起作用
  ReadTimeout: 10000
  ConnectTimeout: 10000

项目启动,注意默认会触发 超时降级

2.3 资源隔离触发降级场景

详情见 Spring Cloud Hystrix(二)