Zuul过滤器
Zuul其实包含了两个功能:路由和过滤器。路由的功能是负责将外部请求转发到具体的微服务实例上,过滤器的功能则是负责对请求的处理过程进行干预,是实现请求校验,是在微服务之间实现切面的处理。
1、过滤器特性
Zuul过滤器的关键特性:
- Type:定义在请求执行过程中何时被执行
- Execution Order:当存在多个过滤器时,用来指示执行的顺序,值越小越早执行
- Criteria:执行的条件,即该过滤器何时被处罚
- Action:该过滤器具体要执行的动作。
实现一个自定义过滤器时需要实现的方法:
- filterType()方法返回过滤器的类型
- filterOrder()方法返回过滤器的执行顺序
- shouldFilter()方法判断是否需要执行该过滤器
- run()方法是该过滤器所要执行的具体过滤动作。
2、过滤器类型及生命周期
Zuul中4种标准的过滤器类型:
- PRE过滤器:在请求被路由之前调用,可用来上线身份验证、在集群中选择请求的微服务、记录调试信息。
- ROUTING过滤器:在调用目前服务之前被调用,用来处理一些动态理由。如A/B测试。
- POST过滤器:在目标微服务执行后,所返回的结果在送回给客户端时被调用。可以实现为响应添加标准的HTTP Header、数据采集、统计信息和指标、审计日志处理。
- ERROR过滤器:在处理请求过程中发生错误时被调用,可以使用实现对异常、错误的统一处理。
请求整体流程:
- 对于任何注册到Zuul服务网关上的PRE过滤器,在请求被路由之前,该类型的过滤器可以对请求进行监控或修改,但是不可以将服务请求重新定位到不同的服务中。
- 当Zuul执行了PRE过滤器后,服务请求就会被转发到ROUTING过滤器中执行,ROUTING过滤器执行时可以将服务请求根据需要分发到不同的服务实例中执行。
- 根据ROUTING过滤器处理的结果调用相应的服务进行处理。
- 当目标服务执行后,Zuul将转回执行所注册的POST过滤器,在该过滤器中,我们对返回客户端的结果进行处理。
- 一旦处理过程中发生错误,那么就会转入ERROR过滤器中执行,对异常、错误进行统一处理。
3、自定义Zuul过滤器
4、禁用Zuul过滤器
禁用上面的TestFilter中PRE过滤器。
5、Error过滤器
基于Zuul过滤器进行的逻辑,我们可以添加一个全部异常处理。
新增一个类型为Error的过滤器,在该过滤器中将错误信息写入RequestContext中,这样SendErrorFile就可以获取该错误信息,并转发到Spring Boot中进行通用的错误处理。
@EnableZuulServer与@EnableZuulProxy比较
@EnableZuulProxy注解包含了@EnableZuulServer的所用功能,并加入了@EnableCircuitBreaker和@EnableDiscoveryClient。
1、EnableZuulServer注解的过滤器
PRE类型过滤器
- ServletDetectionFilter:最先执行的,主要用来检查当前请求是通过Spring的DispatcherServlet处理运行的,还是通过ZuulServlet来处理运行的。
- FormBodyWrapperFilter:将符合要求的请求体包装成FormBodyRequestWrapper对象,供后续处理使用。
- DebugFilter:当请求参数中设置了debug参数时,该过滤器将当前请求上下文中的debugRouting和debugRequest设置为true,后续的过滤器可以根据这两个参数信息定义一些deub信息。
ROUTE类型过滤器
- SendForwardFilter:只对请求上下文中存在forward.to参数的请求进行处理。
POST类型过滤器
- SendResponseFilter:是对代理请求所返回的相应进行封装,然后作为本地请求的相应发送给请求者。
Error类型过滤器
- SendErrorFilter:判断当前请求上下文中是否有异常信息,判断的标准是RequestContext.getThrowable()是否不为空。
2、EnableZuulProxy注解的过滤器
@EnableZuulProxy则在@EnableZuulServer的基础上做了增加。
PRE类型过滤器
- PreDecorationFilter:根据提供的RouteLocator确定路由到的地址,以及怎样去路由。
ROUTE类型过滤器
- RibbonRoutingFilter:会针对上下文中存在serviceId的请求进行处理,使用Ribbon、Hystrix和可插拔的HTTP客户端发送请求,并将服务实例的请求结果返回。
- SimpleHostRoutingFilter:检测到routeHost参数设置时,则会通过Apache HttpClient向指定的URL发送请求。此时,该请求不会使用HystrixCommand进行包装,所以这类请求没有线程隔离和服务容错保护功能。