在微服务架构中存在多个直接调用的服务,这些服务若在调用时出现故障会导致连锁效应,可能会让整个系统变得不可用,这种情况叫做雪崩,Hystix 为了解决这个问题。
Hystix 使用自己的线程池,这样和主应用服务器线程池隔离,如果调用花费很长时间,会停止调用,不同的命令或命令组能够配置它们各自的线程池,可以隔离不同的服务。
Hystix 使用
引入依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
开启 Hystix ,启动类上加 @EnableCircuitBreaker
@EnableDiscoveryClient
@EnableCircuitBreaker
@SpringBootApplication
public class ConsumeApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumeApplication.class, args);
    }
}
或者可以使用 @SpringCloudApplication
@SpringCloudApplication
public class ConsumeApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumeApplication.class, args);
    }
}
//SpringCloudApplication 包含了它们3
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public @interface SpringCloudApplication {
}
然后在消费者 consume 使用 @HystrixCommand
@RestController
public class ConsumeController {
    @Autowired
    private RestTemplate restTemplate;
    
    @GetMapping("/callhello")
    @HystrixCommand(fallbackMethod = "callHelloFailback")
    public String callHello(){
        String url = "http://user-service/user/hello";
       return restTemplate.getForObject(url,String.class);
    }
    public String callHelloFailback(){
        return "服务器繁忙";
    }
}
然后模拟服务提供端超时等情况,这里直接在 user-service 睡眠一会
@RequestMapping("/user")
public class UserController {
    @GetMapping("/hello")
    public String hello() throws InterruptedException {
        Thread.sleep(2000);
        return "hello";
    }
}
注意的是,Hystrix 超时时间默认是1000ms,如果 Ribbon 设置的超时时间小于或等于 Hystix的超时时间,那么重试机制将不会没有被触发,而是直接出发 Hystix。
Hystix 超时时间可以配置:
# 设置hystrix的超时时间为6000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000