Zuul的内置过滤器详解(源码解析)

Zuul的内置过滤器详解(源码解析)

从技术角度来说,Zuul的的核心就是一系列的过滤器。这些过滤器都实现了ZuulFilter接口。

Zuul的过滤器ZuulFilter与Spring的过滤器Filter有什么区别?

 

一,ZuulFilter

 

ZuulFilter是一个抽象类。ZuulFilter实现了IZuulFilter接口、Comparable接口。

继承ZuulFilter的类需要实现下面4个方法:

filterType():过滤器类型,可选值有4个,pre、route、post、error。

filterOrder():过滤器执行的优先级。当某种类型的过滤器有多个时,根据优先级依次执行。

shouldFilter():判断过滤器是否需要执行。可以通过这个方法来限制过滤器的执行条件。

run():过滤器的具体执行逻辑。

 

二,pre过滤器

 

1,ServletDetectionFilter

ServletDetectionFilter:检查请求是否经过DispatcherServlet的转发。如果经过,则把

isDispatcherServletRequest置为true,否则置为false。

 

2,FormBodyWrapperFilter

filterOrder=-1

解析表单数据,并为请求重新编码。

 

3,DebugFilter

 

调试过滤器。源码很简单:

RequestContext ctx =

RequestContext.getCurrentContext();

ctx.setDebugRouting(true);

ctx.setDebugRequest(true);

该过滤器可以控制debug日志的打印。如果需要打印debug日志,我们可以这样设置:

zuul.debug.request=true

这样就可以打印相关的debug日志,这对于我们定位zuul的问题有帮助。例如下面这段代码:

if(RequestContext.getCurrentContext().debugRouting()){…}

Zuul会根据debugRoute来判断是否打印这条日志信息。

 

4,PreDecorationFilter

根据提供的RouteLocator,设置路由地址。还会设置这些属性:requestURI、proxy、

retryable、forward.to、serviceId、Host等属性。

 

5,TracePreZuulFilter

结合Sleuth实现链路追踪功能。

 

6,Servlet30WrapperFilter

对原始请求进行包装,为什么要包装一下呢?包装就是为了拿过来,然后有必要的话方便扩展。

原始请求:HttpServletRequest

包装后请求:Servlet30RequestWrapper

 

三,route过滤器

 

1,SendForwardFilter

这个过滤器的优先级是500,在route过滤器的实现中是最大的。也就是说三个route过滤器,SendForwardFilter最后执行。

SendForwardFilter过滤器的执行需要满足下面的条件:

RequestContext中包含属性:forward.to

RequestContext中包含属性:sendForwardFilter.ran并且值为true

SendForwardFilter是根据forward.to配置的url来转发请求的。

RequestDispatcher dispatcher = cxt.getRequest().getRequestDispatcher(path);

if(dispatcher != null){

    ctx.set("sendForwardFilter.ran", true);

    if(!ctx.getResponse().isCommited()){

        dispatcher.forward(cxt.getRequest(), ctx.getResponse());

        ctx.getResponse().flushBuffer();

    }

}

SendForwardFilter与下面两种过滤器的区别是:SendForwardFilter使用ApplicationDispatcher来转发请求。

 

2,RibbonRoutingFilter

RibbonRoutingFilter过滤器的执行需要满足下面的条件:

RequestContext中不包含属性:routeHost

RequestContext中包含属性:serviceId

RequestContext中包含属性:sendZuulResponse并且值为true

RibbonRoutingFilter与SendForwardFilter的区别是RibbonRoutingFilter使用robbin来请求微服务。

 

3,SimpleHostRoutingFilter

SimpleHostRoutingFilter过滤器的执行需要满足下面的条件:

RequestContext中包含属性:routeHost

RequestContext中包含属性:sendZuulResponse并且值为true

SimpleHostRoutingFilter与RibbonRoutingFilter的区别是:RibbonRoutingFilter使用robbin来请求微服务,而SimpleHostRoutingFilter是通过HttpClient来转发请求。

 

四,post过滤器

 

1,SendResponseFilter

SendResponseFilter主要做两件事:

// 从RequestContext中取出微服务的响应结果,然后封装到HttpServletResponse中。

this.addResponseHeaders();

// 把响应结果写入输出流,发送给客户端。

this.writeResponse()

 

五,error过滤器

 

1,SendErrorFilter

转发请求到/error。这里的路径是可配置的。

首先会从ZuulException中拿到具体的异常信息:

RequestContext ctx = RequestContext.getCurrentContext();

ZuulException exception = this.findZuulException(ctx.getThrowable());

HttpServletRequest request = ctx.getRequest();

然后把异常信息放到request,最后转发请求到指定路径。

RequestDispatcher dispatcher = request.getRequestDispatcher(this.errorPath);

if(dispatcher != null){

    ctx.set("sendErrorFilter.ran", true);

    if(!ctx.getResponse().isCommited()){

        dispatcher.forward(request, ctx.getResponse())

    }

 

六,Zuul内置的特殊过滤器

 

zuul还提供了一类特殊的过滤器,分别为:StaticResponseFilter和SurgicalDebugFilter

StaticResponseFilter:StaticResponseFilter允许从Zuul本身生成响应,而不是将请求转发到源。也就是说,Zuul接收到请求后,直接返回给客户端,不再转发给其他微服务。

SurgicalDebugFilter:SurgicalDebugFilter允许将特定请求路由到分隔的调试集群或主机。

 

六,Zuul过滤器的优先级

 

ServletDetectionFilter:-3

Servlet30WrapperFilter:-2

FormBodyWrapperFilter:-1

SendErrorFilter:0

DebugFilter:1

PreDecorationFilter:5

RibbonRoutingFulter:10

SimpleHostRoutingFilter:100

SendForwardFilter:500

SendResponseFilter:1000

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值