jiangtie 2019-12-20
1、Zuul过滤器生命周期
Zuul大部分功能都是通过过滤器来实现的,Zuul定义了4种标准的过滤器类型,这些过滤器类型对应于请求的典型生命周期。
a、pre: 这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在集群中选择请求的微服务,记录调试信息等。
b、routing: 这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用apache httpclient或netflix ribbon请求微服务。
c、post: 这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的http header、收集统计信息和指标、将响应从微服务发送给客户端等。
e、error: 在其他阶段发送错误时执行该过滤器。
除了默认的过滤器类型,zuul还允许创建自定义的过滤器类型。例如,可以定制一种static类型的过滤器,直接在zuul中生成响应,而不将请求转发到后端的微服务。
zuul请求的生命周期如下图,该图详细描述了各种类型的过滤器的执行顺序。
2、核心过滤器
我们可以在源码中查看和了解它们,它们定义在spring-cloud-netflix-core模块的org.springframework.cloud.netflix.zuul.filters包下。
如上图所示,在默认启用的过滤器中包含了三种不同生命周期的过滤器,这些过滤器都非常重要,可以帮助我们理解Zuul对外部请求处理的过程,以及帮助我们如何在此基础上扩展过滤器去完成自身系统需要的功能。
2、DebugFilter过滤器源码讲解
package org.springframework.cloud.netflix.zuul.filters.pre; import javax.servlet.http.HttpServletRequest; import com.netflix.config.DynamicBooleanProperty; import com.netflix.config.DynamicPropertyFactory; import com.netflix.config.DynamicStringProperty; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.constants.ZuulConstants; import com.netflix.zuul.context.RequestContext; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.DEBUG_FILTER_ORDER; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; public class DebugFilter extends ZuulFilter { private static final DynamicBooleanProperty ROUTING_DEBUG = DynamicPropertyFactory .getInstance().getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, false); private static final DynamicStringProperty DEBUG_PARAMETER = DynamicPropertyFactory .getInstance().getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "debug"); @Override public String filterType() { return PRE_TYPE; } @Override public int filterOrder() { return DEBUG_FILTER_ORDER; } @Override public boolean shouldFilter() { HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); if ("true".equals(request.getParameter(DEBUG_PARAMETER.get()))) { return true; } return ROUTING_DEBUG.get(); } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); ctx.setDebugRouting(true); ctx.setDebugRequest(true); return null; } }
当请求参数中设置了debug参数时,该过滤器会将当前请求上下文中的RequestContext.setDebugRouting()和RequestContext.setDebugRequest()设置为true,这样后续的过滤器可以根据这两个参数信息定义一些debug信息,当生产环境出现问题时,我们就可以通过增加该参数让后台打印出debug信息,以帮助我们进行问题分析。对于请求中的debug参数的名称,我们可以通过zuul.debug.parameter进行自定义。
要想实现Filter,通过继承ZuulFilter然后重写上面的4个方法,就可以实现一个简单的过滤器,下面就相关注意点进行说明
filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:
pre:可以在请求被路由之前调用
route:在路由请求时候被调用
post:在route和error过滤器之后被调用
error:处理请求时发生错误时被调用
filterOrder:通过int值来定义过滤器的执行顺序
shouldFilter:返回一个boolean类型来判断该过滤器是否要执行,所以通过此函数可实现过滤器的开关。在上例中,我们直接返回true,所以该过滤器总是生效
run:过滤器的具体逻辑。在该函数中,我们可以实现自定义的过滤逻辑,来确定是否要拦截当前的请求,不对其进行后续的路由,或是在请求路由返回结果之后,对处理结果做一些加工等。
2、架构图zuul 像其他微服务一样作为一个微服务向eureka server注册,并且能够通过注册列表获取所有的可用服务,其内部默认实现了ribbon,可达到负载均衡的目的,此时的微服务架构图如下: