zuul作为netflix组件,可以与Ribbon、Eureka和Hystrix等组件相结合,的实现负载均衡,熔断器的功能。默认情况下,zuul和ribbon相结合实现负载均衡功能,此处在zuul上实现熔断器。
此处先实现一个zuul-eureka-ribbon的熔断功能,当zuul-eureka-client出现故障时,eureka-ribbon无法调用则进入熔断逻辑,向浏览器输入一句错误信息。
一、在zuul-eureka-ribbon的pom添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
启动类添加 @EnableHystrix 注解开启熔断功能。
修改RibbonService,在hello方法上添加熔断注解,配置回退逻辑方法:
@HystrixCommand(fallbackMethod = "helloError")
public String hello(){
String url = "http://zuul-eureka-client/hi";
return restTemplate.getForObject(url,String.class);
}
public String helloError(){
return "此处无法调用zuul-eureka-client的实例,发生故障,在这里处理熔断逻辑!";
}
二、依次启动zuul-server、zuul-eureka-client的两个实例、zuul-eureka-ribbon。
浏览器访问:http://localhost:8003/hello
浏览器交替显示:
hello ! im zuul-eureka-client! 端口:8001
hello ! im zuul-eureka-client! 端口:8002
三、停止zuul-eureka-client-1 实例,浏览器则只显示: hello ! im zuul-eureka-client! 端口:8002
继续停止zuul-eureka-client-2 会看到浏览器显示:
可以看到已经成功进入熔断逻辑处理方法,说明我们的熔断故障成功。
四、此时 恢复启动 zuul-eureka-client的两个实例。
在zuul实现熔断器功能需要实现ZuulFallbackProvider的接口。实现此接口又两个方法,一个是getRoute(),用于指定个熔断功能应用于哪些路由的服务;另一个是fallbackResponse(),为进入熔断功能执行的逻辑。
首先实现一个接口类:
public interface ZuulFallbackProvider {
public String getRoute() ;
public ClientHttpResponse fallbackResponse();
}
在创建实现该接口的类:
@Component
public class MyFallbackProvider implements ZuulFallbackProvider{
@Override
public String getRoute() {
// return "zuul-eureka-client"; //这里针对zuul-eureka-client服务
return "*"; //这里针对多有服务
}
@Override
public ClientHttpResponse fallbackResponse() {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return 200;
}
@Override
public String getStatusText() throws IOException {
return "ok";
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("zuul 网关调用远程服务发生错误!".getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}
启动zuul-cloud-client服务(此处需要先将ribbon. eureka.enabled修改为false):
浏览器访问:http://localhost:9000/v1/ribbonapi/hello
浏览器交替显示:
hello ! im zuul-eureka-client! 端口:8001
hello ! im zuul-eureka-client! 端口:8002
此时停止zuul-cloud-client的两个实例,会发现无法访问:
据说是因为超时时间太短,那么需要在zuul-cloud-client添加配置:
ribbon:
ReadTimeout: 3000
ConnectTimeout: 3000
此时再重启服务,会发现可以正常进入熔断处理逻辑了: