说明

HystixNetflix 开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。
Hystix 可以解决雪崩问题,Hystix 解决雪崩问题的手段主要是服务降级,包括

  • 线程隔离/服务降级
  • 服务熔断

    服务降级demo

    在之前的 ribbon-demo 例子(SpringCloud_Ribbon.md中有步骤)中,接着做下面的操作
    user-consumer 中添加 Hystix 的依赖
    1. <!-- Hystrix启动器 -->
    2. <dependency>
    3. <groupId>org.springframework.cloud</groupId>
    4. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    5. </dependency>
    在启动类上开启 Hystrix 支持
    @EnableHystrix
    1. package com.it.learn;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    5. import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    6. import org.springframework.context.annotation.Bean;
    7. import org.springframework.web.client.RestTemplate;
    8. @SpringBootApplication
    9. @EnableHystrix
    10. public class UserConsumerApplication {
    11. public static void main(String[] args) {
    12. SpringApplication.run(UserConsumerApplication .class);
    13. }
    14. // 注册RestTemplate的对象到Spring的容器中
    15. @Bean
    16. @LoadBalanced
    17. public RestTemplate restTemplate(){
    18. return new RestTemplate();
    19. }
    20. }
    编写降级逻辑
  1. 编写降级的方法,与原方法返回值,参数列表保持一致
  2. 在需要降级的方法降级注解,@HystrixCommand(fallbackMethod=”降级方法名”)
    1. package com.it.learn.controller;
    2. import com.it.learn.pojo.User;
    3. import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.web.bind.annotation.PathVariable;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import org.springframework.web.bind.annotation.RestController;
    8. import org.springframework.web.client.RestTemplate;
    9. @RestController
    10. @RequestMapping("consumer")
    11. public class UserController {
    12. // 发送基于http协议的远程过程调用(2个服务器相互调用)
    13. @Autowired
    14. private RestTemplate restTemplate;
    15. @RequestMapping("/{id}")
    16. @HystrixCommand(fallbackMethod = "findUserByIdForFail")
    17. public User findUserById(@PathVariable("id") Long id){
    18. String url = "http://user-service/user/" + id;
    19. // 查询
    20. User user = restTemplate.getForObject(url, User.class);
    21. return user;
    22. }
    23. /**
    24. * 降级处理的方法,与原方法返回值,参数列表保持一致
    25. * @param id
    26. * @return
    27. */
    28. public User findUserByIdForFail(@PathVariable("id") Long id){
    29. User user = new User();
    30. user.setId(id);
    31. user.setName("网页丢失了");
    32. return user;
    33. }
    34. }
    Hystrix 默认降级时间为1秒钟,也可以自己配置降级时间
    1. server:
    2. port: 8085
    3. spring:
    4. application:
    5. name: user-consumer # 给服务起名称
    6. eureka:
    7. client:
    8. service-url:
    9. defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka
    10. instance:
    11. ip-address: 127.0.0.1 # 配置服务器ip地址
    12. prefer-ip-address: true # 更倾向于使用ip,而不是host名
    13. instance-id: ${eureka.instance.prefer-ip-address}:${server.port} # 自定义实例的id
    14. hystrix:
    15. command:
    16. default:
    17. execution.isolation.thread.timeoutInMilliseconds: 1500 # 单位毫秒
    18. logging:
    19. level:
    20. com.it.learn: debug
    接着,可以重启 user-consumer 测试,可以在 user-service 上打一个断点,故意延时1.5秒后才放行,可以看到服务已降级
    SpringCloud_Hystix - 图1
    SpringCloud_Hystix - 图2

    服务熔断

    1秒发送20个请求,这20个请求都没有拿到预期的响应结果,对着20个请求进行服务降级处理
    此时断路器打开,后续再有请求来时,直接进行服务降级
    5秒后将断路器设置为中间状态,找一个线程试着去访问,如果访问成功则关闭断路器,服务可以正常运行
    如果未能访问成功,则继续打开断路器
    SpringCloud_Hystix - 图3
    熔断器有3种状态
  • 熔断器默认为关闭状态: 一切正常
  • 中间(半开)状态: 会发送一个请求进行尝试
  • 开启状态: 后续所有的请求自动进行服务降级处理(默认5s,进入半开状态),默认请求下访问20次请求,百分之50失败,就开启熔断器
    1. hystrix:
    2. command:
    3. default:
    4. execution.isolation.thread.timeoutInMilliseconds: 2000
    5. circuitBreaker:
    6. errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%
    7. sleepWindowInMilliseconds: 10000 # 熔断后休眠时长,默认值5秒
    8. requestVolumeThreshold: 10 # 触发熔断的最小请求次数,默认20
    demo
    hystix-demo