在微服务架构中存在多个直接调用的服务,这些服务若在调用时出现故障会导致连锁效应,可能会让整个系统变得不可用,这种情况叫做雪崩,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
网友评论