美文网首页
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