Spring Cloud 核心过滤器
在Spring Cloud Zuul中, 为了让 API 网关组件可以被更方便地使用, 它在 HTTP 请求 生命周期的各个阶段默认实现了一批核心过滤器, 它们会在 API 网关服务启动的时候被自 动加载和启用 。 我们可以在源码中查看和了解它们, 它们定义于 Spring Cloud Zuul netflix-core 模块的 org.springframework.cloud.ne七flix.zuul.filters 包下。 如下图所示,在默认启用 的过滤器中包含三种不同生命周期的过滤器, 这些过滤器都 非常重要,可以帮助我们理解Zuul对外部请求处理的过程,以及帮助我们在此基础上扩展 过滤器去完成自身系统需要的功能。
下面, 我们将逐个对这些过汜器做详细的介绍。
pre过滤器 :
Servle七De七ec七ionFil七er: 它的 执行顺序为-3' 是最先被执行的过滤器。 该过 滤器总是会被执行, 主要用来检测当前请求是通过Spring的DispatcherServlet 处理运行的,还是通过Zuu1Servle七来处理运行的。它的检测结果会以布尔类型保 存在当前请求上下文的isDispatcherServletRequest参数 中,这样在后续的过 滤器中, 我们就可以通过Reques七U巨ls.is区spa七cherServletRequest() 和RequestU巨ls.is ZuulServletRequest()方法来判断请求处理的源头, 以 实现后续不同的处理机制。 一般情况下, 发送到API网关的外部请求都会被 Spring 的 DispatcherServlet 处理, 除了通过/zuul尸路径访问的请求会绕过 贮spatcherServlet, 被Zuu1Servlet处理, 主要用来应对处理大文件上传的 情 况。 另外, 对千 Zuu1Servlet 的访问路径 /zuul /*, 我 们可以通过 zuul.servletPath参数来进行修改。Servlet30WrapperFilter: 它的执行顺序为-2, 是第二个执行的过滤器。 目前 的实现会对所有请求生效, 主要为了将原始的 H七七pServletRequest 包装成 Servlet30Reques七Wrapper对象。
FormBodyWrapperF辽ter: 它的执行顺序为-1, 是第三个执行的过滤器。 该过滤 器仅对两类请求生效, 第 一 类是Con七ent-Type 为 app巨cation/x-wwwform-urlencoded 的请求 , 第二类是Conten七-Type 为 multipart/formda七a 并且是由Spring 的区spatcherServle七 处 理的请求(用到 了 ServletDetec七ionFilter 的处理结果)。 而该过滤器的主要目的是将符合要求 的请求体包装成FormBodyRequestWrapper对象。
DebugFilter: 它的执行顺序为1, 是第四个执行的过滤器。 该过滤器会 根据配置 参数 zuul.debug.reque江和请求 中的debug参数来决定是否执行 过滤器中的 操作。 而它的具 体操作内容则 是将当前请求上下文中的 debugRou巨ng 和 debugReque江参数设置为true。 由千 在同 一 个请求 的不同生命周期中都可以访 问到这两个值, 所以我们 在 后续的各个过滤器中可以利用这两个值来定义 一 些 debug 信息 , 这样当线上环境出现问题的时候, 可以通过请求参数的方式来激活这 些debug信息以帮助分析问题。 另外,对千请求参数中的debug参数 , 我们也可以 通过zuul.debug.parameter 来进行自定义。
PreDecorationFilter: 它的执行顺序为5, 是pre阶段最后被 执行的过滤器。 该过滤器会判断当前请求上下文中 是否存在forward.七o和service工d参数 ,如 果都 不存在, 那么它就会 执行 具体 过滤器的操作(如果有一个存在的话, 说明当前 请求已经被处理 过了, 因为这两个信息就是根据当前请求 的路由信息加载进来的)。 而它的具体操作内容就是为当前请求做一些预处理 , 比如, 进行 路由规则的匹配、 在请求上下文中设置该请求 的基本信息以及将路由匹配结果等一 些设置信息等, 这 些 信息 将是后续 过滤器进行处理的重要依据, 我们可以通过 RequestContext. getCurren七Context ()来 访问这些信息。 另外, 我们还可以在该实现中找到一 些 对HTTP头请求 进行处理的逻辑, 其中包含了 一 些耳熟能详的头 域 , 比如 X-Forwarded-Host、 X-Forwarded-Por七。 另外,对于这些头域的记录是通过 zuul.addProxyHeaders参数进行控制的, 而这个参数的默认 值为 七rue, 所以 Zuul在请求跳转时默认会 为请求增加X-Forwarded-*头域 , 包括X-ForwardedHost、 X-Forwarded-Port、 X-Forwarded-For、 X-Forwarded-Prefix、 X-Forwarded-Proto。也可以通过设置zuul.addProxyHeaders = false关闭 对这些头域的添加动作
route过滤器 :
RibbonRoutteingFilter: 它的执行顺序为10, 是route阶段第一 个执行的过滤 器。 该过滤器只对请求上下文中存在serviceid参数的请求进行处理, 即只对通 过service工d配置路由规则的请求生效。 而该过滤器的执行逻辑就是面向服务路 由的核心, 它通过使用Ribbon和Hystrix来向服务实例发起请求, 并将服务实例的 请求结果返回。
SimpleHostRou巨ngFilter: 它的执行顺序为100, 是route阶段第二个执行 的过滤器。 该过滤器只对请求上下文中存在routeHo江参数的请求进行处理, 即 只对通过url 配置路由规则的请求生效。 而该过滤器的执行逻辑就是直接向 routeHos七参数的物理地址发起请求, 从源码中我们可以知道该请求是直接通过 h巨 pc口ent包实现的, 而没有使用 Hystrix命令进行包装, 所以这类请求并没 有线程隔离和断路器的保护。
SendForwardFilter: 它的执行顺序为500,是route阶段第三个执行的过滤器。 该过滤器只对请求上下文中存在forward.to参数的请求进行处理,即用来处理路 由规则中的 forward本地跳转配置。
post过滤器 :
SendErrorFilter: 它的执行顺序为o, 是 post阶段第一 个执行的过滤器。 该 过滤器仅在请求上下文中包含 error.status_code 参数(由之前执行的过滤器 设置的错误编码)并且还没有被该过滤器处理过的时候执行。 而该过滤器的具体逻 辑就是利用请求上下文中的错误信息来组成一 个forward到API网关/error错误 端点的请求来产生错误响应。
SendPesponseFil ter: 它的执行顺序为1000, 是post阶段最后执行的过滤器。 该过滤器会检查请求上下文中是否包含请求响应相关的头信息、 响应数据流或是响 应体, 只有在包含它们其中 一 个的时候执行处理逻辑。 而该过滤器的处理逻辑就是 利用请求上下文的响应信息来组织需要发送回客户端的响应内容。