SpringCloud>09 - zuul 进阶(过滤器等)

扯淡:

上一章】介绍了zuul的基本使用以及几种路由规则的配置,本章将介绍zuul消息回退,文件上传、过滤器。过滤器一般用在权限认证方面,避免在每一个服务中独立做验证。     

springboot、springcloud、docker学习目录:【传送门】 

Fallback 消息回退:

zuul中默认集成了Hystrix断路器,拥有Hystrix消息回退的功能。

在zuul中,当一个路由被断开时,你可以通过创建一个FallbackProvider来提供一个回退响应。您需要指定回退的路由ID,并提供一个ClientHttpResponse作为回退响应。

1、创建FallbackProvider类:

/**
 * @Auther: xf
 * @Date: 2018/12/26 20:35
 * @Description: zuul消息回退 参考官网
 */
@Component
public class MyFallbackProvider implements FallbackProvider {

    /**
     * route id
     *  “*” 代表所有
     */
    @Override
    public String getRoute() {
        return "springcloud-article";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, final Throwable cause) {
        if (cause instanceof HystrixTimeoutException) {
            return response(HttpStatus.GATEWAY_TIMEOUT);
        } else {
            return response(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    private ClientHttpResponse response(final HttpStatus status) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return status;
            }
            @Override
            public int getRawStatusCode() throws IOException {
                return status.value();
            }
            @Override
            public String getStatusText() throws IOException {
                return status.getReasonPhrase();
            }
            @Override
            public void close() {
            }
            @Override
            public InputStream getBody() throws IOException {
                // 响应
                return new ByteArrayInputStream((getRoute() + " : " + "zuul fallback").getBytes());
            }
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

2、测试:

2.1、启动Eureka、zuul、文章微服务

2.2、通过zuul请求文章微服务:

http://127.0.0.1:8050/springcloud-article/article/1 

2.2.1、没有断点:正常返回。

2.2.2、打上断点

a、没有配置消息回退:返回默认页面

b、配置了消息回退:

zuul文件上传:

1、官网:

大概意思:如果你使用了zuul代理,只要文件很小,就可以使用代理路径来上传文件。对于较大的文件,可以使用"/zuul/**"这个路径。如果代理路径走了Ribbon,对于特别大的文件需要设置超时。

2、application.yml:

############### 通过 zuul 上传大文件 在前加 /zuul 前缀 小文件不需要 ##################
############ zuul 上传大文件会超时 #########
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
ribbon:
  ConnectTimeout: 3000
  ReadTimeout: 60000

3、zuul文件上传的使用:

3.1、小文件上传路径:

     127.0.0.1:8050/springcloud-file/file/upload

3.2、大文件:

     127.0.0.1:8050/zuul/springcloud-file/file/upload

三、zuul过滤器:

1、自定义过滤器,继承ZuulFilter:

/**
 * @Auther: xf
 * @Date: 2018/12/26 21:25
 * @Description:  Zuul 过滤器
 */
@Component
public class CustomZuulFilter extends ZuulFilter {

    /**
     * 过滤器类型
     * pre: 请求被路由前调用
     * route:路由时调用
     * post:在route和error过滤器之后被调用  zuul自定义了许多过滤器
     * error:处理请求发送错误调用
     */
    @Override
    public String filterType() {
        return "pre";
    }
    // 多个过滤器执行顺序  优先级为0,数字越大,优先级越低
    @Override
    public int filterOrder() {
        return 0;
    }
    // 是否执行该过滤器,此处为true,说明需要过滤
    @Override
    public boolean shouldFilter() {
        return true;
    }
    // 过滤器执行的操作 返回任意Object 类型的值都表示继续执行
    @Override
    public Object run() throws ZuulException {

        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String header = request.getHeader("Authorization");

        /**
         * 经过网关的请求会请求两次,
         * 1、内部负责分发的请求  方法:OPTIONS  此请求时不会携带  Authorization 头信息的 所以必须放行
         * 2、转发到微服务的请求  http://localhost:8082/article/1
         */
        if(request.getMethod().equals("OPTIONS")){
            System.out.println("options");
            return null;  // return null 表示放行
        }
        // 登录的请求 放行
        String url=request.getRequestURL().toString();
        if(url.indexOf("/admin/login")>0){
            System.out.println("登陆页面"+url);
            return null;
        }

        // 防止token被伪造,一般会在token前面加 约定好的字符串
        if(null != header && header.startsWith("Bearer ")){
            // 获取 token
            String token = header.substring(7);
            try{
                // 这里一般做解析 token 验证权限等信息操作
                // 方便测试,token固定 123
                if("123".equals(token)){
                    // token 验证通过 转发 header
                    requestContext.addZuulRequestHeader("Authorization", header);
                    return null;  // 放行
                }
            } catch (Exception e){
                // 禁止通行
                requestContext.setSendZuulResponse(false);
            }
        }
        requestContext.setResponseStatusCode(401);
        requestContext.setResponseBody("没有权限");
        requestContext.setSendZuulResponse(false);
//        requestContext.getResponse().setContentType("text/html;charset=UTF-8");
        // 返回json
        requestContext.getResponse().setContentType("application/json;charset=UTF-8");
        return null;
    }
}

2、测试(相关服务已启动):

2.1、请求接口:http://127.0.0.1:8050/springcloud-article/article/1

2.2、添加请求头再次访问:

至此,自定义过滤器生效。

总结:

1、zuul中集成了Hystrix,可以实现fallback。
2、zuul文件上传,小文件不作配置,大文件添加前缀"/zuul/**",超大文件配置Hystrix超时时间。
3、zuul过滤器的使用,不同于spring中的过滤器。一般用在权限认证中。 

代码地址:

https://gitee.com/cpla026/springcloud/tree/master/springcloud_parent/springcloud_zuul


个人学习分享
更多 springboot、springcloud、docker 文章,关注微信公众号吧:

猜你喜欢

转载自blog.csdn.net/cp026la/article/details/86609149
今日推荐