SpringCloud Netflix Hystrix

2020-02-16 16:04:48来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

SpringCloud Netflix Hystrix

 

Hystrix的一些概念

Hystrix是一个容错框架,可以有效停止服务依赖出故障造成的级联故障。

和eureka、ribbon、feign一样,也是Netflix家的开源框架,已被SpringCloud集成。

 

线程隔离

 

将每个请求都包装为一个线程,放到线程池中,对这些请求的处理(线程)互不干扰,隔离开来,某些请求出问题也不会影响到其他请求。

 

服务监控

监控请求的失败率(一定时间内,请求失败个数)达到阈值,就打开断路器,熔断链路,使后续的请求快速失败。

 

 

服务限流

当此消费者对某提供者请求个数较多时,消费者会限制请求个数,有2种策略:

(1)线程池。

新建一个线程池(使用的不是tomcat的线程池,而是jdk自带的线程池),将对某个提供者的每个请求都包装为一个单独的线程,放到线程池中,线程池中的线程(请求)都是正在处理的。若线程池满了,放在队列中排队等待,若队列也满了,后续该消费者对该提供者的请求直接快速失败。

Hystrix默认使用线程池。

 

(2)信号量

信号量即可同时处理的请求个数。指定一个初始值(信号量),比如10,

该消费者调用一次该提供者,即一个信号进来了,自动将信号量就-1,如果处理完,自动将信号量+1,

信号量为0时不再处理后续请求,直接快速失败。

 

 

服务降级

不管是什么原因导致的服务调用失败,快速失败后浏览器显示的都是一片英文(错误信息),这对用户不友好。

一般快速失败后是执行一个预案(备胎),来代替对服务的调用,预案使用相同参数表、返回值类型,调用服务失败后会自动调用预案来处理(回退)。

 

 

自我修复

自我修复其实就是断路器状态的切换。

断路器打开后5min内的请求都快速失败(断路器打开,链路熔断),5min后会向提供者发送一些请求(断路器半开,放行部分请求),

如果成功,说明问题已修复,放行所有请求(断路器关闭,链路恢复通行),否则继续下一个5min。

这个5min是窗口期,数值可以调的。

 

 


 

 

 

Hystrix的使用

Hystrix是在消费者中使用的。

 

(1)pom.xml

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

 

 

(2)引导类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix  //使用Hystrix进行断路保护,也可以使用@EnableCircuitBreaker,这2个注解作用差不多
public class UserServer {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

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

}

 

 

(3)在调用服务的方法上指定回退方法(备胎)

@Controller
@RequestMapping("/user")
public class UserController {
    private OrderFeignService orderFeignService;

    @Autowired
    public void setOrderFeignService(OrderFeignService orderFeignService) {
        this.orderFeignService = orderFeignService;
    }

    //根据用户id查找用户所有订单
    @GetMapping("/order/{user_id}")
    @ResponseBody
    @HystrixCommand(fallbackMethod = "findOrdersByUserIdFb")
    public List<Order> findOrdersByUserId(@PathVariable Integer user_id){  //调用服务的方法
        List<Order> orderList = orderFeignService.findOrdersByUserId(user_id);
        return orderList;
    }

    //回退方法,参数表、返回值要和调用服务的一致
    public List<Order> findOrdersByUserIdFb(Integer user_id){
        return null;
    }

}

如果调用服务出现问题,比如网络波动、或者本身代码出错,会退而求其次(服务降级),调用回退方法来处理。并非传一堆英文的错误信息给浏览器。

不管使用REST、还是Feign,@HystrixCommand都是这么标的(标在controller|service的调用方法上)。

注意如果回退方法返回null,使用时要先判断是否为null。

 

 


 

 

 

可以指定一些其他参数,比如调用服务的超时时间、线程池的大小:

@HystrixCommand(fallbackMethod = "findOrdersByUserIdFb",
        commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")},
        threadPoolProperties = {@HystrixProperty(name = "coreSize",value = "10")})

都是数组形式,一个@HystrixProperty指定一个参数,key、value都是字符串形式,可以指定多个参数(要不怎么使用数组)。

调用服务的超时时间默认是1000ms,即1s。

 

 

我怎么知道有哪些参数?

github上搜hystrix找到官方 -> WiKi -> 点击右侧的目录中的Configuration即可查看所有参数的用法。

直达车:https://github.com/Netflix/Hystrix/wiki/Configuration

 

 

参数也可以直接写在类上:

@Controller
@RequestMapping("/user")
@DefaultProperties(defaultFallback = "findOrdersByUserIdFb",
        commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")},
        threadPoolProperties = {@HystrixProperty(name = "coreSize",value = "10")}
)
public class UserController {
    //.......
}

写在类上则对此类中所有调用服务的方法都有效。

 

 


 

 

 

使用Feign自带的Hystrix

上面的方式是REST、Fegin都通用的,此外还有一种方式,Feign本身已经集成了Hystrix,可以使用Feign自带的Hystrix。

 

(1)pom.xml    依然要加入Hystrix的依赖。

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

 

 

(2)application.properties  开启feign自带的hystrix

feign.hystrix.enabled=true

 

 

因为使用的是Feign自带的Hystrix,所以在引导类中开启Feign即可,不必再开启Hystrix:

@EnableFeignClients
// @EnableHystrix

 

 

(3)写一个类实现Feign接口,就和Feign接口放在同一个包下

@Component  //要放到spring容器中
public class OrderFeignServiceFb implements OrderFeignService {

   //回退方法 @Override
public List<Order> findOrdersByUserId(Integer user_id) {return null; }
}

因为是implements,参数表、返回值类型都是相同的,实现的方法就是Feign接口中对应方法的回退方法(备胎)。

 

 

(3)在Feign接口中指定对应的回退类(就是上面那个类)

@Component
@FeignClient(name = "order-server",fallback = OrderFeignServiceFb.class)
public interface OrderFeignService {

    @PostMapping("/order/findAllByUserId")
    List<Order> findOrdersByUserId(@RequestParam("user_id") Integer user_id);

}

 

 


 

 

 

2种方式的区别

  • 第一种

是在service|controller中的方法上标注,正因为如此,是通用的,对REST、Feign都适用,

但设置的参数:回退方法、超时时间等都是对service|controller中方法的设置,比如:

    //根据用户id查找用户所有订单
    @GetMapping("/order/{user_id}")
    @ResponseBody
    @HystrixCommand(fallbackMethod = "findOrdersByUserIdFb")
    public List<Order> findOrdersByUserId(@PathVariable Integer user_id){
        List<Order> orderList = orderFeignService.findOrdersByUserId(user_id);  //服务调用
        int i = 1 / 0; //出错,调用回退方法
        return orderList;
    }

就算服务调用本身没问题,这个方中出现其它问题也会调用回退方法;设置的超时时间是整个方法执行的超时时间,不单单是服务调用。

 

 

  • 第二种

只能对Feign使用,不能对REST使用,但设置的回退方法是服务调用出问题才执行的,如果调用了回退方法,那肯定是服务调用出现了问题。

 

 

 

 


原文链接:https://www.cnblogs.com/chy18883701161/p/12315059.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:JavaSwing开发简单的银行管理系统 附源码

下一篇:打开UML类图的正确姿势