zuul的使用,过滤规则配置

LD is tigger forever,CG are not brothers forever, throw the pot and shine forever.
Modesty is not false, solid is not naive, treacherous but not deceitful, stay with good people, and stay away from poor people.
talk is cheap, show others the code,Keep progress,make a better result.

目录

概述

架构特性

设计思路

实现思路分析

1.核心逻辑

  ​zuul的核心逻辑都是由一系列filter过滤器链实现的,但是filter的类型不同,执行的时机也不同,效果自然也不一样,主要特点如下: ​ filter的类型:filter的类型,决定了它在整个filter链中的执行顺序,可能在端点路由前执行,也可能在端点路由时执行,还有可能在端点路由后执行,甚至是端点路由发生异常时执行。 ​ filter的执行顺序:同一种类型的filter,可以通过filterOrder()方法设置执行顺序,一般都是根据业务场景自定义filter执行顺序。 ​ filter执行条件:filter运行所需的标准,或条件。 ​ filter执行效果:符合某个filter执行条件,产生执行效果。 ​ zuul内部有一套完整的机制,可以动态读取编译运行filter机制,filter与filter之间不直接通信,在请求线程中会通过RequestContext来共享状态,它内部是用ThreadLocal实现的,例如HttpServletRequest、HttpServletResponse、异常信息等。部分源码如下:

2。主控制类

zuul中不同类型的filter执行逻辑的核心在ZuulServlet类中,主要代码如下:

public class ZuulServlet extends HttpServlet {
private static final long serialVersionUID = -3374242278843351500L;
private ZuulRunner zuulRunner;
@Override
public void init(ServletConfig config) throws ServletException {
    super.init(config);
 
    String bufferReqsStr = config.getInitParameter("buffer-requests");
    boolean bufferReqs = bufferReqsStr != null && bufferReqsStr.equals("true") ? true : false;
 
    zuulRunner = new ZuulRunner(bufferReqs);
}
 
@Override
public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
    try {
        init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
 
        // Marks this request as having passed through the "Zuul engine", as opposed to servlets
        // explicitly bound in web.xml, for which requests will not have the same data attached
        RequestContext context = RequestContext.getCurrentContext();
        context.setZuulEngineRan();
 
        try {
	        //如果preRoute方法在执行的时候出现异常,直接就抛出500异常,不会走catch中的error方法,见下图FilterProcessor类中的preRoute方法。
            preRoute(); 
        } catch (ZuulException e) {
			//如果preRoute在执行过程中,抛出Zuul异常,这里被捕捉到以后,会执行error方法,打印堆栈信息,见下图FilterProcessor类中的error方法。
			error(e); 
            postRoute();
            return;
        }
        try {
            route();
        } catch (ZuulException e) {
            error(e);
            postRoute();
            return;
        }
        try {
            postRoute();
        } catch (ZuulException e) {
            error(e);
            return;
        }
 
    } catch (Throwable e) {
        error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
    } finally {
        RequestContext.getCurrentContext().unset();
    }
  }  //.......
}

生命周期

pre:在zuul网关按照规则路由到下级服务之前执行,如果需要对请求进行预处理,可以使用这种类型的过滤器。如:认证鉴权,限流等。
route:这种过滤器是zuul路由动作的执行者,是Apache HttpClient或Ribbon构建和发送原始HTTP请求的地方,现在也支持OKHTTP。
post:这种过滤器是在端点请求完毕,返回结果或者发生异常后执行的filter。如果需要对返回的结果进行再次处理,可以在这种过滤中处理逻辑。
error: 这种过滤器是在整个生命周期内,如果发生异常,就执行该filter,可以做全局异常处理。

自定义Filter

public class PreFilter extends ZuulFilter {
 
    /**
     * filter类型
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }
 
    /**
     * 同一个类型下的filter的执行顺序
     */
    @Override
    public int filterOrder() {
        return 0;
    }
 
    /**
     * 为true时 run执行
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }
 
    @Override
    public Object run() throws ZuulException {
        System.out.println("这是一个自定义的zuulFilter");
        //RequestContext 支持多个filter 执行传递参数   相当于ThreadLocal
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String a = request.getParameter("a");
        if(a == null){
            //对改请求禁止路由,即禁止访问下游服务
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseBody("error");
            requestContext.set("key", false);
            return null;
        }
        requestContext.set("key", true);
        return null;
    }
}

3.2.自定义PostFilter类集成ZuulFilter

public class PostFilter extends ZuulFilter {
 
    /**
     * filter类型
     */
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }
 
    /**
     * 同一个类型下的filter的执行顺序
     */
    @Override
    public int filterOrder() {
        return 0;
    }
 
    /**
     * 为true时 run执行
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }
 
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        requestContext.getResponse().setCharacterEncoding("UTF-8");
        String responseBody = requestContext.getResponseBody();
        if(responseBody != null){
            requestContext.setResponseStatusCode(500);
            requestContext.setResponseBody(responseBody);
        }
        System.out.println("  post filter ");
        return null;
    }
}
@EnableEurekaClient
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(ZuulApplication.class);
 
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
        LOGGER.info("================ zuul start success ==============");
    }
 
    @Bean
    public PreFilter preFilter(){
        return new PreFilter();
    }
 
    @Bean
    public PostFilter postFilter(){
        return new PostFilter();
    }
}

相关工具如下:

实验效果:(解决思路)

分析:

小结:

主要讲述了一些zuul的使用,过滤规则配置,里面有许多不足,请大家指正~

参考资料和推荐阅读

1.链接: 参考资料.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值