本来是不想更,因为毕设还没做,但是这次如果因为毕设放弃了,下次就可能因为别的事情而不更,所以还是坚持更。(虽然没什么人看)
本篇建议有SpringCloud开发基础的猿看,当然,也不是必须只能在SpringCloud中使用Zuul。
至于为什么使用网关,请自行百度,我只对Zuul进行一个剖析。
zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用。可以提供基于JVM的路由器和服务器端负载均衡器功能。
zuul 能做什么?
Zuul可以通过加载动态过滤机制,从而实现以下各项功能:
验证与安全保障: 识别面向各类资源的验证要求并拒绝那些与要求不符的请求。
审查与监控: 在边缘位置追踪有意义数据及统计结果,从而为我们带来准确的生产状态结论。
动态路由: 以动态方式根据需要将请求路由至不同后端集群处。
压力测试: 逐渐增加指向集群的负载流量,从而计算性能水平。
负载分配: 为每一种负载类型分配对应容量,并弃用超出限定值的请求。
静态响应处理: 在边缘位置直接建立部分响应,从而避免其流入内部集群。
多区域弹性: 跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。
除此之外,Zuul还可以实现精确路由与压力测试。
另外,Zuul的规则引擎基本上允许用任何JVM语言来编写规则和过滤器,内置对Java和Groovy的支持。
Zuul 可以提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。
一般情况下,Zuul是嵌入到SpringMVC的 DispatchServlet机制中。 也就是说,Spring MVC可以控制路由。 在这种情况下,Zuul被配置为缓冲请求。 如果需要在不缓冲请求的情况下绕过Zuul(例如对于大文件上传),在请求时需要再请求路径中通过添加/zuul的方式来绕过zuul。 此路径(/zuul)可以使用zuul.servlet-path属性进行更改。
zuul的核心是一系列的filters(这里的filter不是servlet中的filter哦), 其作用可以类比Servlet框架的Filter,或者AOP。 在zuul把Request route到用户处理逻辑的过程中,这些filter参与一些过滤处理,比如Authentication,Load Shedding等。
(1)Zuul可以对过滤器进行动态的加载,编译,运行。
(2)Zuul的过滤器之间没有直接的相互通信,他们之间通过一个RequestContext的静态类来进行数据传递的。RequestContext类中有ThreadLocal变量来记录每个Request所需要传递的数据。
(3)Zuul的过滤器是由Groovy写成,这些过滤器文件被放在Zuul Server上的特定目录下面,Zuul会定期轮询这些目录,修改过的过滤器会动态的加载到Zuul Server中以便过滤请求使用。
Zuul大部分功能都是通过过滤器来实现的。Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。
1) PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
2) ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
3) POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
4) ERROR:在其他阶段发生错误时执行该过滤器。
内置的特殊过滤器
zuul还提供了一类特殊的过滤器,分别为:StaticResponseFilter和SurgicalDebugFilter
StaticResponseFilter:StaticResponseFilter允许从Zuul本身生成响应,而不是将请求转发到源。
SurgicalDebugFilter:SurgicalDebugFilter允许将特定请求路由到分隔的调试集群或主机。
自定义的过滤器
除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。
Zuul Filter的生命周期
Zuul请求的生命周期如图,该图详细描述了各种类型的过滤器的执行顺序。
太具体的我不在说了,怎么写demo,自己百度,网上的demo你绝对看不完。
Zuul 架构图
要想使用Zuul,需要在启动类上添加@EnableZuulProxy注解。使用@EnableZuulProxy注解后,在Spring容器初始化时,会将Zuul的相关配置初始化(旧版本是通过@EnableZuulProxy注解中@Import的一个类实现的,在最新版里也有@Import,但是我在最新版里找到的那个@Import只是一个标志类,幸运的是,我在netflix-core的jar包中看到了ZuulServerAutoConfiguration,这个配置类跟老版本的@Import的类及其相似,所以我猜测最新版本应该是通过ZuulServerAutoConfiguration来实现的,有99%的把握吧,哈哈哈),其中包含一个Spring Boot的bean:ServletRegistrationBean,该类主要用于注册Servlet。Zuul提供了一个ZuulServlet类。zuulservlet(这里的servlet就是J2EE中的Servlet了)中有一个zuulRunner对象,该对象中初始化了RequestContext,RequestContext作为存储整个请求的一些数据(包括整个过程的HTTP请求、HTTP响应、状态等数据),并被所有的zuulfilter共享。zuulRunner中还有 FilterProcessor。FilterProcessor作为执行所有的zuulfilter的管理器。FilterProcessor从filterloader 中获取zuulfilter,而zuulfilter是被filterFileManager所加载,并支持groovy热加载(采用了轮询的方式热加载)。
在zuul中, 整个请求的过程是这样的,首先将请求给zuulservlet处理,在Servlet的service方法中,执行各种Zuul过滤器(ZuulFilter)。ZuulServlet的service方法接收到请求后,会执行“pre”阶段的过滤器,再执行“routing”阶段的过滤器,最后执行“post”阶段的过滤器。其中“routing”的过滤器,会将请求转发到“源服务”,源服务可以是第三方的Web服务,也可以是Spring Cloud的集群服务。在执行pre和routing阶段的过滤器时,如果出现异常,则会执行“error”过滤器。有了这些filter之后,zuulservelet首先执行的Pre类型的过滤器,再执行route类型的过滤器,最后执行的是post 类型的过滤器,如果在执行这些过滤器有错误的时候则会执行error类型的过滤器。执行完这些过滤器,最终将请求的结果返回给客户端。
前面说Zuulservlet作为类似于Spring MVC中的DispatchServlet,起到了前端控制器的作用,所有的请求都由它接管。它的内部到底是怎么工作的?
它的核心代码如下:
可以看到:
(1)如果执行pre类型的filter抛出ZuulException则执行error类型的filter,再执行post类型的filter。
(2)如果执行route类型的filter抛出ZuulException则执行error类型的filter,再执行post类型的filter。
(3)如果执行post类型的filter抛出ZuulException则执行error类型的filter。
(4)如果在抛出其他异常,或者在catch ZuulException后执行发生异常,则执行error类型的filter。
得做毕设了,有空再续。