美文网首页
Zuul过滤器的执行者FilterProcessor

Zuul过滤器的执行者FilterProcessor

作者: 鸿雁长飞鱼龙潜跃 | 来源:发表于2019-07-29 18:02 被阅读0次

    一,FilterProcessor的主要成员

    Zuul的内置过滤器主要有4种:pre过滤器、route过滤器、post过滤器、error过滤器。

    FilterProcessor对外提供以下4个方法:

    1,pre过滤器执行逻辑

    preRoute()

    2,route过滤器执行逻辑

    route()

    3,post过滤器后执行逻辑

    postRoute()

    4,error过滤器执行逻辑

    error()

    最终都会调用:

    this.runFilters(type);

    二,FilterProcessor.runFilters

    FilterProcessor的具体实现就是:

    FilterProcessor.runFilters(type);

    下面我们分步来说明:

    1,根据类型拿到过滤器集合

    List<ZuulFilter> filters = FilterLoader.getInstance().getFiltersByteType(type);

    2,遍历过滤器集合,执行过滤器逻辑

    ZuulFilter zuilFilter = list.get(i);

    Object result = this.processZuulFilter(zuulFilter);

    这里会调用ZuulFilter.runFilter()来执行具体的过滤器处理逻辑,然后对处理结果进行一个包装,包装成ZuulFilterResult返回。ZuulFilterResult有三种情况:

    SUCCESS:过滤器执行成功

    FAILED:过滤器执行失败。

    SKIPPED:过滤器被跳过。每个过滤器都有一个是否执行的方法shouldFilter(),这个方法定义了过滤器的执行条件。如果一个过滤器不满足执行条件,那么这个过滤器执行时就会被跳过。

    三,ZuulFilter.runFilter

    this.processZuulFilter()最终会调用ZuulFilter.runFilter()。

    这里思考一个问题:为什么不把ZuulFilter.runFilter()的逻辑直接写在FilterProcessor类里面?

    ZuulFilter.runFilter()的执行逻辑如下:

    1,判断当前过滤器是否被禁用

    判断当前过滤器是否被禁用,如果没有被禁用,继续执行下面的逻辑,否则直接返回。我们可以通过下面的配置项来禁用过滤器:

    zuul.过滤器类名.过滤器类型.disabled

    比如我们禁用DebugFilter,可以这样配置:

    zuul.DebugFilter.pre.disabled=true

    2,判断当前过滤器是否满足执行条件

    判断当前过滤器是否满足执行条件,调用过滤器的shouldFilter()方法进行判断。如果满足执行条件,则开始执行,如果不满足执行条件,则把执行状态置为SKIPPED返回。

    if (this.shouldFilter()){

        // 调用过滤器的具体实现类的run()方法

        Object res = this.run();

        return new ZuulFilterResult(res, ExecutionStatus.SUCCESS);

    } else {

        // 跳过当前过滤器

        return new ZuulFilterResult(res,

            ExecutionStatus.SKIPPED);

    }

    3,进入具体的ZuulFilter实现类,执行真正的过滤器逻辑。

    Object res = this.run();

    这里的run()方法,是IZuulFilter接口中定义的方法,这个方法的实现有很多,Zuul定义的内置过滤器,都继承了ZuulFilter,也就是间接实现了IZuulFilter。

    我们以RibbonRoutingFilter为例来看看过滤器的具体逻辑。RibbonRoutingFilter是route过滤器,执行具体的路由操作,也就是转发请求到指定的微服务。

    第一步:拿到RequestContext。这个流程基本上每个过滤器都要执行,因为RequestContext是各个过滤器之间通信的一个通道。

    RequestContext context = RequestContext.

    getCurrentContext();

    第二步:把RequestContext包装成RibbonCommandContext

    RibbonCommandContext commandContext

    = this.buildCommandContext(context);

    第三步:调用dispatch转发请求到指定微服务。

    ClientHttpResponse response =

    this.forward(commandContext);

    this.setResponse(response);

    return response;

    在this.forward(conmandContext)方法中,根据RibbonCommandContext创建RibbonCommand,然后调用RibbonCommand的execute()执行转发。

    RibbonCommand command =

    this.ribbonCommandFactory.create(context);

    ClientHttpResponse response =

    command.execute();

    return response;

    四,到底是谁转发了Zuul请求

    RibbonCommand是一个空接口,没有定义任何方法。但是继承了HystrixExecutable<ClientHttpResponse>接口。也就是说RibbonCommand.execute()实际上就是HystrixExecutable.execute()。

    RibbonCommand的实现有2个:

    HystrixCommand

    HystrixCollapser

    这两个实现的逻辑基本相似:

    return this.queue().get();

    这里把请求的转发交给了线程,然后通过Future获取到线程的执行结果返回给Ribbon

    总之,最终是由Hystrix负责请求的转发。

    相关文章

      网友评论

          本文标题:Zuul过滤器的执行者FilterProcessor

          本文链接:https://www.haomeiwen.com/subject/qnrirctx.html