Spring Cloud 断路器 Hystrix

服务消费者中加入断路器

首先我们需要在服务消费者中引入hystrix,如下:

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

修改服务消费者启动入口类

引入hystrix之后,我们需要在入口类上通过@EnableCircuitBreaker开启断路器功能,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@EnableCircuitBreaker
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonConsumerApplication {

public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApplication.class, args);
}
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}

我们也可以使用一个名为@SpringBootApplication的注解代替这三个注解,@SpringBootApplication注解的定义如下:

1
2
3
4
5
6
7
8
9
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public @interface SpringCloudApplication {
}

实际上就是这三个注解的一个整合。

修改Controller

然后我们创建一个HelloService类,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Service
public class HelloService {
@Autowired
private RestTemplate restTemplate;

@HystrixCommand(fallbackMethod = "error")
public String hello() {
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class);
return responseEntity.getBody();
}

public String error() {
return "error";
}
}

关于这个HelloService类我说如下几点:

1.RestTemplate执行网络请求的操作我们放在HelloService中来完成。
2.error方法是一个请求失败时回调的方法。
3.在hello方法上通过@HystrixCommand注解来指定请求失败时回调的方法。

OK,最后我们将ConsumerController的逻辑修改成下面这样:

1
2
3
4
5
6
7
8
9
@RestController
public class ConsumerController {
@Autowired
private HelloService helloService;
@RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)
public String helloController() {
return helloService.hello();
}
}

此时我们就开启了断路器功能。

测试

我们先确认服务注册中心,两个服务提供者的实例,端口号分别是8080和8081,一个服务消费者,端口号为9000,一共四个实例都启动成功,启动成功之后,我们再关掉一个服务提供者,此时访问http://localhost:9000/ribbon-consumer,结果如下:

图片

OK,们看到,此时如果服务调用失败,就会调用失败的那个回调方法。

事实上,不仅仅是服务提供者被关闭时我们需要断路器,如果请求超时也会触发熔断请求,调用回调方法返回数据。