• 111541

    文章

  • 803

    评论

  • 12

    友链

  • 最近新加了换肤功能,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

SpringCloud 微服务 (十四) 服务网关 Zuul 过滤器(Pre&Post)

撸了今年阿里、腾讯和美团的面试,我有一个重要发现.......>>

上篇学习了zuul路由,这边继续学习,粗糙的记录zuul过滤器的用法

 

现在对请求url做个约定,在请求url上没有带参数key=123的url全部过滤掉

①localhost:7000/product/list?key=1234         ---不过滤

②localhost:7000/product/list                        ---过滤,不执行

完成以上功能,在gateway服务中,代码如下 : 

package com.cloud.gateway.filters;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * 常量类
 * 过滤器状态 FilterConstants
 * 请求状态 HttpStatus
 * 引用其中的属性值即可,无需自己写
 */
@Component
public class PreFilter extends ZuulFilter {
    /**
     * filter类型
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * filter执行顺序,值越小优先级越高
     * 官方推荐使用x-1方式优先排序
     * @return
     */
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    /**
     * filter 开启关闭
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 实现filter逻辑
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request =requestContext.getRequest();
        String key=request.getParameter("key");

        //如果不存在,则设置没有权限不通过,状态为401
        if (StringUtils.isEmpty(key)){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

浏览器访问成功则返回list列表,失败则返回错误页面,错误码:401

 

再来实现一个post过滤器,在得到结果之后,实现在post filter阶段,返回response的,给header头部加点信息,代码如下: 

package com.cloud.gateway.filters;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;

/**
 * 常量类
 * 过滤器状态 FilterConstants
 * 请求状态 HttpStatus
 * 引用其中的属性值即可,无需自己写
 */
@Component
public class PostFilter extends ZuulFilter {
    /**
     * filter类型
     *
     * @return
     */
    @Override
    public String filterType() {
        return POST_TYPE;
    }

    /**
     * filter执行顺序,值越小优先级越高
     * 官方推荐使用x-1方式优先排序
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return SEND_RESPONSE_FILTER_ORDER - 1;
    }

    /**
     * filter 开启关闭
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 实现filter逻辑
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletResponse response = requestContext.getResponse();
        response.setHeader("POST-UUID", UUID.randomUUID().toString());
        return null;
    }
}

 

浏览器控制台 请求信息 : 

 

写了两次, 套路也都摸清了,能写的地方也就这么几个点,后面再做 限流 操作,结合上面学的,限流做在请求filter最靠前的地方,比鉴权pre前执行,不然流量都进去了,这里需要一个算法---令牌桶算法,这个算法很多地方已经实现了,拿来用即可,意思是以一定速率将令牌放入桶中,桶中的令牌满了,就不会再放进去了,外部的请求进入,请求将获得桶中的令牌,得令牌者可通行,没有令牌请求将被拒绝

下面代码实现 : 

package com.cloud.gateway.filters;

import com.cloud.gateway.exceptions.RateLimiterException;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;

/**
 * 限流
 */
@Component
public class RateLimiterFilter extends ZuulFilter {

    //create 每秒放入100个令牌
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(100);

    /**
     * filter类型
     *
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * filter执行顺序,值越小优先级越高
     * 官方推荐使用x-1方式优先排序
     * 选择最高优先级SERVLET_DETECTION_FILTER_ORDER,并-1
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return SERVLET_DETECTION_FILTER_ORDER - 1;
    }

    /**
     * filter 开启关闭
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 实现filter逻辑
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        //判断--获取通行令牌-->如果没有令牌不等于之前的没有权限401,可以抛出自定义异常或者其他处理
        if (!RATE_LIMITER.tryAcquire()) {
            throw new RateLimiterException();
        }

        return null;
    }
}

自定义异常: 

package com.cloud.gateway.exceptions;

public class RateLimiterException extends RuntimeException {
}

 

以上是过滤器的简单示例

还有一个Zuul关于鉴权的使用,涉及新建user服务,也会用到docker、redis,刚刚入手mac,上面什么都没有,装好了再继续下面的学习实践

 

---------------------------------------------------------


695856371Web网页设计师②群 | 喜欢本站的朋友可以收藏本站,或者加入我们大家一起来交流技术!

0条评论

Loading...


自定义皮肤 主体内容背景
打开支付宝扫码付款购买视频教程
遇到问题联系客服QQ:419400980
注册梁钟霖个人博客