Spring Cloud学习笔记(九)-网关Zuul使用熔断器和过滤器

说明:本文仅作为本人学习<<深入理解Spring Cloud与微服务构建>>一书的学习笔记,所有代码案例及文字描述均参考该书,不足之处,请留言指正,不胜感激.
一.在Zuul上配置熔断器
  上一篇提到zuul的起步依赖集成了ribbon和hystrix,接下来我们来看看如何在网关上实现熔断功能.
  首先我们需要了解在Zuul中实现熔断功能需要实现ZuulFallbackProvider的接口.实现该接口有两个方法,一个是getRoute()方法,用于指定熔断功能应用于哪个路由服务;另一个方法fallbackResponse()为进入熔断功能时执行的逻辑.具体实现可以参看如下代码:

/**
 * 网关熔断配置
 *
 * @author zhyu
 * @version v1.0
 * @date 2018年07月03日 19:54:28
 */
@Component
public class MyZuulFallbackProvider implements ZuulFallbackProvider {
    @Override
    public String getRoute() {
        //实现对producer-server服务的熔断
        return "producer-server";
        //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("{\"status\":500,\"message\":\"sorry,the system goes to sleep,please try again later!\"}".getBytes());
            }

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

接着我们启动eureka-server,zuul-server服务,不启动producer-server服务,然后通过网关访问producer-server的接口,结果如下:
这里写图片描述
可见,熔断器配置起了作用,如果我们将getRoute()方法的返回改为”*”,那么将对所有的路由服务都加熔断功能.
二.在Zuul中使用过滤器
  在Zuul中自定义过滤器很简单,只需要继承ZuulFilter,并实现它的抽象方法就好,最后将其注入到IoC容器,如下:

package com.example.zuulserver.Filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;

/**
 * 自定义过滤器
 * 实现起来很简单,只需要继承ZuulFilter,并实现它的抽象方法
 * @author zhyu
 * @version v1.0
 * @date 2018年07月05日 19:11:49
 */
@Component
public class MyZuulFilter extends ZuulFilter {
    /**
     * 返回过滤器的类型
     * @return
     */
    @Override
    public String filterType() {
        /**
         * Zuul有一下四种过滤器
         * "pre":是在请求路由到具体的服务之前执行,这种类型的过滤器可以做安全校验,例如身份校验,参数校验等
         * "routing":它用于将请求路由到具体的微服务实例,在默认情况下,它使用Http Client进行网络请求
         * "post":它是在请求已被路由到微服务后执行,一般情况下,用作收集统计信息,指标,以及将响应传输到客户端
         * "error":它是在其他过滤器发生错误时执行
         */
        return "pre";
    }

    /**
     * 过滤顺序,值越小,越早执行该过滤器
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 表示该过滤器是否过滤逻辑,如果是ture,则执行run()方法;如果是false,则不执行run()方法.
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 具体的过滤逻辑
     * 本例中,检查请求的参数中是否传了token这个参数,如果没传,则请求不被路由到具体的服务实例,
     * 直接返回响应,状态码为401
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");
        if(token == null){
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            try{
                ctx.getResponse().getWriter().write("token is empty");
            }catch(Exception e){

            }
        }
        return null;
    }
}

然后我们启动服务,当我们不带token时,浏览器显示如下:
这里写图片描述
这次我们带上token,再访问:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/fly_zhaohy/article/details/80904043
今日推荐