通过之前发布的《Spring Cloud构建微服务架构(五)服务网关》一文,相信大家对于Spring Cloud Zuul已经有了一个基础的认识。通过前文的介绍,我们对于Zuul的第一印象通常是这样的:它包含了对请求的路由和过滤两个功能,其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础;而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。然而实际上,路由功能在真正运行时,它的路由映射和请求转发都是由几个不同的过滤器完成的。其中,路由映射主要通过pre类型的过滤器完成,它将请求路径与配置的路由规则进行匹配,以找到需要转发的目标地址;而请求转发的部分则是由route类型的过滤器来完成,对pre类型过滤器获得的路由地址进行转发。所以,过滤器可以说是Zuul实现API网关功能最为核心的部件,每一个进入Zuul的HTTP请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。
下面,我们就通过本文来详细了解一下Spring Cloud Zuul的过滤器!以下内容节选自《Spring Cloud微服务实战》,稍做加工。
过滤器
在Spring Cloud Zuul中实现的过滤器必须包含4个基本特征:过滤类型、执行顺序、执行条件、具体操作。这些元素看着似乎非常的熟悉,实际上它就是ZuulFilter接口中定义的四个抽象方法:
1
2
3
4
5
6
7
|
String filterType();
int filterOrder();
boolean shouldFilter();
Object run();
|
它们各自的含义与功能总结如下:
- filterType:该函数需要返回一个字符串来代表过滤器的类型,而这个类型就是在HTTP请求过程中定义的各个阶段。在Zuul中默认定义了四种不同生命周期的过滤器类型,具体如下:
- pre:可以在请求被路由之前调用。
- routing:在路由请求时候被调用。
- post:在routing和error过滤器之后被调用。
- error:处理请求时发生错误时被调用。
- filterOrder:通过int值来定义过滤器的执行顺序,数值越小优先级越高。
- shouldFilter:返回一个boolean类型来判断该过滤器是否要执行。我们可以通过此方法来指定过滤器的有效范围。
- run:过滤器的具体逻辑。在该函数中,我们可以实现自定义的过滤逻辑,来确定是否要拦截当前的请求,不对其进行后续的路由,或是在请求路由返回结果之后,对处理结果做一些加工等。
请求生命周期
上一节中,对于Spring Cloud Zuul中的过滤器类型filterType,我们已经做过一些简单的介绍,Zuul默认定义了四个不同的过滤器类型,它们覆盖了一个外部HTTP请求到达API网关,直到返回请求结果的全部生命周期。下图源自Zuul的官方WIKI中关于请求生命周期的图解,它描述了一个HTTP请求到达API网关之后,如何在各个不同类型的过滤器之间流转的详细过程。
从上图中,我们可以看到,当外部HTTP请求到达API网关服务的时候,首先它会进入第一个阶段pre,在这里它会被pre类型的过滤器进行处理,该类型的过滤器主要目的是在进行请求路由之前做一些前置加工,比如请求的校验等。在完成了pre类型的过滤器处理之后,请求进入第二个阶段routing,也就是之前说的路由请求转发阶段,请求将会被routing类型过滤器处理,这里的具体处理内容就是将外部请求转发到具体服务实例上去的过程,当服务实例将请求结果都返回之后,routing阶段完成,请求进入第三个阶段post,此时请求将会被post类型的过滤器进行处理,这些过滤器在处理的时候不仅可以获取到请求信息,还能获取到服务实例的返回信息,所以在post类型的过滤器中,我们可以对处理结果进行一些加工或转换等内容。另外,还有一个特殊的阶段error,该阶段只有在上述三个阶段中发生异常的时候才会触发,但是它的最后流向还是post类型的过滤器,因为它需要通过post过滤器将最终结果返回给请求客户端(实际实现上还有一些差别,后续介绍)。
核心过滤器
在Spring Cloud Zuul中,为了让API网关组件可以更方便的上手使用,它在HTTP请求生命周期的各个阶段默认地实现了一批核心过滤器,它们会在API网关服务启动的时候被自动地加载和启用。我们可以在源码中查看和了解它们,它们定义于spring-cloud-netflix-core模块的org.springframework.cloud.netflix.zuul.filters包下。
如上图所示,在默认启用的过滤器中包含了三种不同生命周期的过滤器,这些过滤器都非常重要,可以帮助我们理解Zuul对外部请求处理的过程,以及帮助我们如何在此基础上扩展过滤器去完成自身系统需要的功能。下面,我们将逐个地对这些过滤器做一些详细的介绍:
pre过滤器
- ServletDetectionFilter:它的执行顺序为-3,是最先被执行的过滤器。该过滤器总是会被执行,主要用来检测当前请求是通过Spring的DispatcherServlet处理运行,还是通过ZuulServlet来处理运行的。它的检测结果会以布尔类型保存在当前请求上下文的isDispatcherServletRequest参数中,这样在后续的过滤器中,我们就可以通过RequestUtils.isDispatcherServletRequest()和RequestUtils.isZuulServletRequest()方法判断它以实现做不同的处理。一般情况下,发送到API网关的外部请求都会被Spring的DispatcherServlet处理,除了通过/zuul/路径访问的请求会绕过DispatcherServlet,被ZuulServlet处理,主要用来应对处理大文件上传的情况。另外,对于ZuulServlet的访问路径/zuul/,我们可以通过zuul.servletPath参数来进行修改。
- Servlet30WrapperFilter:它的执行顺序为-2,是第二个执行的过滤器。目前的实现会对所有请求生效,主要为了将原始的HttpServletRequest包装成Servlet30RequestWrapper对象。
- FormBodyWrapperFilter:它的执行顺序为-1,是第三个执行的过滤器。该过滤器仅对两种类请求生效,第一类是Content-Type为application/x-www-form-urlencoded的请求,第二类是Content-Type为multipart/form-data并且是由Spring的DispatcherServlet处理的请求(用到了ServletDetectionFilter的处理结果)。而该过滤器的主要目的是将符合要求的请求体包装成FormBodyRequestWrapper对象。
- DebugFilter:它的执行顺序为1,是第四个执行的过滤器。该过滤器会根据配置参数zuul.debug.request和请求中的debug参数来决定是否执行过滤器中的操作。而它的具体操作内容则是将当前的请求上下文中的debugRouting和debugRequest参数设置为true。由于在同一个请求的不同生命周期中,都可以访问到这两个值,所以我们在后续的各个过滤器中可以利用这两值来定义一些debug信息,这样当线上环境出现问题的时候,可以通过请求参数的方式来激活这些debug信息以帮助分析问题。另外,对于请求参数中的debug参数,我们也可以通过zuul.debug.parameter来进行自定义。
- PreDecorationFilter:它的执行顺序为5,是pre阶段最后被执行的过滤器。该过滤器会判断当前请求上下文中是否存在forward.to和serviceId参数,如果都不存在,那么它就会执行具体过滤器的操作(如果有一个存在的话,说明当前请求已经被处理过了,因为这两个信息就是根据当前请求的路由信息加载进来的)。而它的具体操作内容就是为当前请求做一些预处理,比如:进行路由规则的匹配、在请求上下文中设置该请求的基本信息以及将路由匹配结果等一些设置信息等,这些信息将是后续过滤器进行处理的重要依据,我们可以通过RequestContext.getCurrentContext()来访问这些信息。另外,我们还可以在该实现中找到一些对HTTP头请求进行处理的逻辑,其中包含了一些耳熟能详的头域,比如:X-Forwarded-Host、X-Forwarded-Port。另外,对于这些头域的记录是通过zuul.addProxyHeaders参数进行控制的,而这个参数默认值为true,所以Zuul在请求跳转时默认地会为请求增加X-Forwarded-*头域,包括:X-Forwarded-Host、X-Forwarded-Port、X-Forwarded-For、X-Forwarded-Prefix、X-Forwarded-Proto。我们也可以通过设置zuul.addProxyHeaders=false关闭对这些头域的添加动作。
《Spring Cloud实战小贴士:Zuul处理Cookie和重定向》 一文中提到的加载敏感头信息加入到忽略头信息的操作调用就在PreDecorationFilter过滤器中实现。
route过滤器
- RibbonRoutingFilter:它的执行顺序为10,是route阶段第一个执行的过滤器。该过滤器只对请求上下文中存在serviceId参数的请求进行处理,即只对通过serviceId配置路由规则的请求生效。而该过滤器的执行逻辑就是面向服务路由的核心,它通过使用Ribbon和Hystrix来向服务实例发起请求,并将服务实例的请求结果返回。
- SimpleHostRoutingFilter:它的执行顺序为100,是route阶段第二个执行的过滤器。该过滤器只对请求上下文中存在routeHost参数的请求进行处理,即只对通过url配置路由规则的请求生效。而该过滤器的执行逻辑就是直接向routeHost参数的物理地址发起请求,从源码中我们可以知道该请求是直接通过httpclient包实现的,而没有使用Hystrix命令进行包装,所以这类请求并没有线程隔离和断路器的保护。
- SendForwardFilter:它的执行顺序为500,是route阶段第三个执行的过滤器。该过滤器只对请求上下文中存在forward.to参数的请求进行处理,即用来处理路由规则中的forward本地跳转配置。
post过滤器
- SendErrorFilter:它的执行顺序为0,是post阶段第一个执行的过滤器。该过滤器仅在请求上下文中包含error.status_code参数(由之前执行的过滤器设置的错误编码)并且还没有被该过滤器处理过的时候执行。而该过滤器的具体逻辑就是利用请求上下文中的错误信息来组织成一个forward到API网关/error错误端点的请求来产生错误响应。
- SendResponseFilter:它的执行顺序为1000,是post阶段最后执行的过滤器。该过滤器会检查请求上下文中是否包含请求响应相关的头信息、响应数据流或是响应体,只有在包含它们其中一个的时候就会执行处理逻辑。而该过滤器的处理逻辑就是利用请求上下文的响应信息来组织需要发送回客户端的响应内容。
这里不列出具体代码了,读者可自行根据类名来查看源码了解详细处理过程。下图是对上述过滤器根据顺序、名称、功能、类型做了综合的整理,可以帮助我们在自定义过滤器或是扩展过滤器的时候用来参考并全面地考虑整个请求生命周期的处理过程。
http://blog.didispace.com/spring-cloud-source-zuul/
http://blog.csdn.net/forezp/article/details/76211680
相关推荐
尽管文档标题和描述较为简单,但可以从这些信息中提炼出关于Spring Cloud项目的源码下载、Spring Cloud的基本概念、用途及其核心组件等方面的内容。 ### Spring Cloud 概念 Spring Cloud 是一个基于Spring Boot...
3. 编写过滤器:根据需求编写自定义过滤器,实现特定功能。 4. 启动Zuul:将Zuul配置为一个独立的服务实例,或者将其与其他Spring Cloud服务(如Eureka)结合部署。 在提供的"zuulTest"文件名中,可能包含的是一个...
4. Zuul或Spring Cloud Gateway源码:了解它们如何处理请求转发,实现API路由和过滤器,以及安全策略的集成。 四、实战应用 1. 分析配置中心Config Server和Client的交互过程,理解如何实现配置的实时更新。 2. ...
Zuul的核心功能在于为微服务提供动态路由、过滤和安全控制,它允许开发者定义一系列预处理和后处理的过滤器,用于执行如身份验证、动态路由、限流等功能。 Zuul的工作原理是在客户端请求到达服务之前,先经过Zuul...
SpringCloud Zuul Gateway 服务网关是Spring Cloud生态系统中的一个重要组件,它主要负责微服务架构中的路由转发和过滤器功能。Zuul是Netflix开源的一个边缘服务,而Gateway则是Spring Cloud针对Zuul进行的升级版,...
SpringCloud Zuul是基于Spring Cloud框架的一个核心组件,它扮演着API网关的角色,负责路由转发、过滤器处理以及安全控制等任务。Zuul的主要功能包括动态路由、过滤器机制、安全控制、负载均衡、健康检查等。下面将...
2. **过滤器**:Zuul的核心功能之一是过滤器,它可以自定义处理请求和响应的过程。过滤器分为四种类型:pre、route、error和post。我们可以根据需求创建自定义过滤器,实现诸如身份验证、限流等功能。 3. **动态...
Zuul的主要功能包括路由转发、过滤器处理、负载均衡、熔断和限流等。在单点登录场景中,Zuul可以拦截所有请求,检查请求是否携带有效的OAuth2令牌,如果未携带或令牌无效,则重定向到登录页面进行身份验证。 **SSO...
**三、Zuul过滤器的使用** 1. **创建自定义过滤器**:可以通过继承ZuulFilter抽象类并重写相关方法来创建自定义过滤器。每个过滤器都需要指定过滤类型和执行顺序。 2. **过滤器生命周期**:过滤器的生命周期包括四...
2. **过滤器机制**:Zuul支持预过滤、路由过滤、post过滤和错误过滤四个阶段的过滤器,可以用于身份验证、日志记录、限流等场景。 3. **动态路由**:可以通过配置中心动态修改路由规则,适应业务变化的需求。 4. **...
这里的代码可能包括了Zuul过滤器的实现以及服务路由的配置。 学习这个例子,你可以了解如何设置Zuul的路由规则,创建自定义过滤器,以及如何与其他Spring Cloud组件(如Eureka和Hystrix)集成。通过实际操作,你会...
7. **Spring Cloud Gateway**:Spring Cloud的最新版本中,Zuul已被Gateway取代,Gateway提供更强大的路由功能和过滤器机制,能够处理更复杂的API管理和路由逻辑。 8. **Spring Cloud OpenFeign**:OpenFeign简化了...
在深入探讨Spring Cloud和微服务构建的过程中,Spring Cloud Zuul是一个关键组件,它扮演着路由网关和熔断器的角色。本文将详细讲解Zuul的功能、原理以及如何在Spring Boot应用中集成和配置。 首先,Spring Cloud ...
压缩包中的 "spring cloud zuul" 可能包含了一个完整的 Spring Cloud Zuul 示例应用,它展示了如何配置和运行 Zuul 服务,包括如何定义路由、编写过滤器、集成安全组件等。这样的示例对于初学者理解和实践 Spring ...
同时,Zuul还支持过滤器,可以实现认证、限流、监控等功能,提高系统的可扩展性和安全性。 3. **Feign**: Feign是SpringCloud的客户端声明式Web服务客户端,它使得编写微服务间的调用更加简洁。开发者只需要定义...
本篇将围绕SpringCloud的核心组件进行源码分析,包括Eureka服务注册与发现、Ribbon客户端负载均衡、Hystrix断路器、Zuul路由网关以及Config分布式配置中心,旨在帮助读者深入理解这些组件的工作原理。 一、Eureka:...
Spring Cloud 是建立在 Spring Boot 基础上,用于简化分布式系统开发的工具集合。它整合了多种服务治理框架,提供了微服务开发所需的各项功能,如服务发现、配置管理、消息总线、负载均衡、断路器、智能路由、分布式...
在给定的压缩包文件中,`EureKaserver` 可能是关于Eureka服务发现的配置或示例,`SpringCloud-Service` 可能包含了一个或多个微服务实例,而`SpringCloud-Zuul` 很可能包含了Zuul 网关的配置和服务。通过这些组件的...
这些视频课程结合源码分析和课件学习,可以帮助开发者深入理解SpringBoot和SpringCloud的核心原理,并掌握实际应用中的最佳实践。对于想要在微服务领域深入发展的IT专业人士来说,这是一个非常有价值的资源。通过...
Zuul是Spring Cloud生态中的一个关键组件,它扮演着边缘服务的角色,负责微服务间的路由转发和过滤器功能。本文将深入探讨Spring Cloud Zuul在微服务架构中的应用和重要性。 1. **Zuul简介** Zuul是Netflix开源的...