Spring Cloud Zuul源码分析

Spring Cloud Zuul中介绍了Zuul 1.x的基本使用,本文从源码角度介绍一下zuul的底层实现。

先来一张zuul的整体流程图。

可以看到Zuul本质上是一个servlet,在这个servlet里面封装了一系列的过滤器,然后再进行请求的转发或者结果的返回。所以下面我们的分析重点就是这个zuul filter。

和之前的源码分析一样,从入口注解@EnableZuulProxy开始。

ZuulProxyConfiguration类稍后再来看,先来看下它的父类ZuulConfiguration。

在ZuulConfiguration中注册了前面说的重点--ZuulServlet。接着就详细的看下这个类。

它继承了HttpServlet,在其init方法中初始化了ZuulRunner。

我们知道servlet中的service方法会在请求到达时执行,ZuulServlet在这里定义了zuul filter中不同方法的执行顺序,pre->route->post,中间若有异常则执行error。随便选一个filter方法进入。

他会调用先前在init方法中初始化的ZuulRunner中的相关方法,执行流程接着就来到ZuulRunner

获取FilterProcessor实例,调用FilterProcessor中的对应方法

在runFilters方法中获取所有该类型的过滤器(这里是获取所有“post”类型的过滤器)并根据filterOrder排序,返回一个过滤器链并依次执行processZuulFilter方法

调用runFilter中执行过滤逻辑

调用shouldFilter判断是否执行过滤,若是再执行run方法自定义逻辑,封装成ZuulFilterResult返回。其中上面提到的shouldFilter,filterOrder,run等方法都是我们自定义过滤器时需要实现的方法。到这里,zuul的核心ZuulServlet就已经分析完了。

除了主要的ZuulFilter,还注册了其他的一些Filter,挑选一个简单的来看一下

上面的DebugFilter类型为“pre”,如果开启debug则执行该过滤器并在RequestContext中设置debug属性。下面这个表格列出了ZuulConfiguration与ZuulProxyConfiguration注册的所有过滤器。

我们在实现自己的Zuul过滤器时,可以参考上面过滤器的实现并设置合适的过滤器类型与order大小。

过滤器已经创建好了,那么存储在哪?

ZuulConfiguration中还包含了一个内部配置类,里面注册了ZuulFilterInitializer

ZuulFilterInitializer类是一个监听器,将在servlet环境启动时执行contextInitialized方法,将所有的过滤器放入FilterRegistry中。

因为zuul支持动态的添加过滤器,所以需要有方法定时的去加载系统中的过滤器。

他会在FilterFileManager中开启定时轮询,扫描系统中的过滤器并加入到过滤器集合中。

回到子类ZuulProxyConfiguration,由于@EnableZuulProxy默认开启了ribbon负载均衡,所以这里主要导入了Ribbon需要的相关配置

到这里分析基本已经结束了,上面的代码基于zuul 1.x,在16年的时候zuul进行了升级,在zuul 2.x中,架构进行调整,整体采用Netty实现,调用方式由原来的阻塞调用变为非阻塞调用,I/O模型变为I/O复用模型(UNIX中的五种I/O模型),相比zuul 1有更高的吞吐量与并发量,里面关于过滤器的部分发生了较大变化,具体见https://github.com/Netflix/zuul/wiki。然而Spring官方并不没有集成zuul 2,因为它们自己开发了一个网关Spring Cloud Gateway,gateway基于Netty与webflux实现,也是异步非阻塞的,如果使用Spring Cloud构建微服务的话,又希望网关有更好的性能,建议使用Spring Cloud Gateway作为自己的网关组件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章