LD is tigger forever,CG are not brothers forever, throw the pot and shine forever.
Modesty is not false, solid is not naive, treacherous but not deceitful, stay with good people, and stay away from poor people.
talk is cheap, show others the code,Keep progress,make a better result.
目录
概述
从Zuul的源码来看,ZuulFilter的加载模式可能跟我们想象的大有不同,Zuul设计的初衷是ZuulFilter是存放在Groovy文件中,可以实现基于最后修改时间进行热加载。我们先看看Zuul核心类之一com.netflix.zuul.filters.FilterRegistry(Filter的注册中心,实际上是ZuulFilter的全局缓存):
实际上Zuul使用了简单粗暴的方式(直接使用ConcurrentHashMap)缓存了ZuulFilter,这些缓存除非主动调用remove方法,否则不会自动清理。Zuul提供默认的动态代码编译器,接口是DynamicCodeCompiler,目的是把代码编译为Java的类,默认实现是GroovyCompiler,功能就是把Groovy代码编译为Java类。还有一个比较重要的工厂类接口是FilterFactory,它定义了ZuulFilter类生成ZuulFilter实例的逻辑,默认实现是DefaultFilterFactory,实际上就是利用Class#newInstance()反射生成ZuulFilter实例。接着,我们可以进行分析FilterLoader的源码,这个类的作用就是加载文件中的ZuulFilter实例:
前面花大量功夫分析完ZuulFilter基于Groovy文件的加载机制(在SpringCloud体系中并没有使用此策略,因此,我们持了解的态度即可)以及RequestContext的设计,接着我们分析FilterProcessor去了解如何使用加载好的缓存中的ZuulFilter。我们先看FilterProcessor的基本属性:
Zuul本来就是设计为Servlet规范组件的一个类库,ZuulServlet就是javax.servlet.http.HttpServlet的实现类,而ZuulServletFilter是javax.servlet.Filter的实现类。这两个类都依赖到ZuulRunner完成ZuulFilter的调用,它们的实现逻辑是完全一致的,我们只需要看其中一个类的实现,这里挑选ZuulServlet:
ZuulServletFilter和ZuulServlet不相同的地方仅仅是初始化和处理方法的方法签名(参数列表和方法名),其他逻辑甚至是代码是一模一样,使用过程中我们需要了解javax.servlet.http.HttpServlet和javax.servlet.Filter的作用去选择到底使用ZuulServletFilter还是ZuulServlet。上面的代码可以看到,ZuulServlet初始化的时候可以配置初始化布尔值参数buffer-requests,这个参数默认为false,它是ZuulRunner实例化的必须参数。ZuulServlet中的调用ZuulFilter的方法都委托到ZuulRunner实例去完成,但是我们可以从service(servletRequest, servletResponse)方法看出四种FilterType(pre、route、post、error)的ZuulFilter的执行顺序,总结如下:
1、pre、route、post都不抛出异常,顺序是:pre->route->post,error不执行。
2、pre抛出异常,顺序是:pre->error->post。
3、route抛出异常,顺序是:pre->route->error->post。
4、post抛出异常,顺序是:pre->route->post->error。
注意,一旦出现了异常,会把抛出的Throwable实例设置到绑定到当前请求线程的RequestContext实例中的throwable属性。还需要注意在service(servletRequest, servletResponse)的finally块中调用了RequestContext.getCurrentContext().unset();,实际上是从RequestContext的ThreadLocal实例中移除当前的RequestContext实例,这样做可以避免ThreadLocal使用不当导致内存泄漏
架构特性
Zuul简单的使用例子
我们做一个很简单的例子,场景是:对于每个POST请求,使用pre类型的ZuulFilter打印它的请求体,然后使用post类型的ZuulFilter,响应结果硬编码为字符串"Hello World!"。我们先为CounterFactory、TracerFactory添加两个空的子类,因为Zuul处理逻辑中依赖到这两个组件实现数据度量:
设计思路
实现思路分析
1.核心逻辑
2。主控制类
相关工具如下:
实验效果:(解决思路)
分析:
小结:
主要讲述了一些Zuul源码分析的使用,过滤规则配置,里面有许多不足,请大家指正~
参考资料和推荐阅读
1.链接: 参考资料.