Zuul-容错与回退

        之前我们是在Zuul项目中集成Hystrix的监控,那么我们启动该服务。然后在Hystrix Dashboard中输入: http://localhost:8280/hystrix.stream,然后进行监控,那么我们将看到如下界面:

        这说明,Zuul已经整合了Hystrix。

spring-cloud-starter-zuul本身已经集成了hystrix和ribbon,所以Zuul天生就拥有线程隔离和断路器的自我保护能力,以及对服务调用的客户端负载均衡功能。但是,我们需要注意,当使用path与url的映射关系来配置路由规则时,对于路由转发的请求则不会采用HystrixCommand来包装,所以这类路由请求就没有线程隔离和断路器保护功能,并且也不会有负载均衡的能力。因此,我们在使用Zuul的时候尽量使用path和serviceId的组合进行配置,这样不仅可以保证API网关的健壮和稳定,也能用到Ribbon的客户端负载均衡功能。

        但Zuul的Hystrix监控的粒度是微服务,而不是某个API,也就是所有经过Zuul的请求都会被Hystrix保护起来。假如,我们现在把Product-Service服务关闭,再来访问会出现什么结果呢?结果可能不是我们所想那样,如下:

         在Zuul中实现熔断功能需要实现FallbackProvider接口。该接口有两个方法,一个是getRoute()方法,用于执定熔断器应用于哪些路由服务;另一个方法fallbackResponse()方法为进入熔断功能是执行的逻辑。FallbackProvider 源码如下:

public interface FallbackProvider {
    String getRoute();

    ClientHttpResponse fallbackResponse(String route, Throwable cause);
}

        实现一个针对eureka-client1服务的熔断器,当eureka-client1的服务组出现故障时,进入熔断逻辑,向浏览器输入一句错误的提示信息,代码如下:

@Component
public class NyZuulFallbackProvider implements FallbackProvider {
    protected Logger logger = LoggerFactory.getLogger(NyZuulFallbackProvider.class);

    @Override
    public String getRoute() {
        // 注意: 这里是route的名称,不是服务的名称,
        // 如果这里写成大写PRODUCT-SERVICE将无法起到回退作用
        return "eureka-client1";
    }

    @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("error! I'm the fallback.".getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
                return headers;
            }
        };
    }
}

重新启动工程,关闭eureka-client1的所有实例,早浏览器上访问http://localhost:8777/hello/yang,浏览器显示:

error! I'm the fallback.

如果需要所有的路由服务都加熔断功能,只需要在getRoute()方法上返回“*”的匹配府,代码如下:

    @Override
    public String getRoute() {
        return "*";
    }

猜你喜欢

转载自blog.csdn.net/u010277958/article/details/88808184
今日推荐