一. zuul网关架构剖析
如上图, zuul网关分为三个部分. 绿色部分, 粉色部分, 蓝色部分.
1. 过滤器管理模块(绿色模块): 让开发人员管理过滤器, 过滤器管理, 主要是上传的动作和激活的动作. 过滤器上传完是保存到数据库中的. 开发人员可以通过界面管理过滤器的状态. 比如,金丝雀线上激活
2. 过滤器加载模块(粉红色模块): 是过滤器加载模块, 定期的扫描过滤器, 看看过滤器有没有变更. 过滤器管理器会先将变更的过滤器拉倒本地的过滤器目录当中. 如果变更了,就会执行Filter Loader进行加载, 加载到网关运行时的filter Runner中
3. 过滤器运行时模块(蓝色模块): 网关过滤器运行时模块. 这个运行时模块本身是一个http servlet, 可以跑在tomcat容器中的. 请求过来以后, 首先交给zuul servlet, zuul servlet再将请求交给zuul filter runner. zuul filter runner是整个网关最核心的组件.
请求会依次经过前置路油过滤器, 路由过滤器, 和后置路由过滤器. 经过过滤以后, 请求会以response的形式响应给客户端. zuul网关最核心的部门就是过滤链, 依次运行过滤器. 有一个组件很重要, 就是Request Context, 当请求在zuul网关过滤链中流转的时候, 他们需要共享一些过滤信息. 比如前置过滤器会设置一些信息,给路由过滤器去读取. 信息的交换是通过Request Context, 就像是过滤器之间可以共享的存储, 而且是线程安全的, 每个请求有一个局部的request context.
二. 请求处理的生命周期
1. 请求过来了, 首先会进入一系列的前置过滤器pre filter.
2. 前置过滤器处理完了, 进入routing filter路由过滤器, routing filter路由过滤器是真正的向后台服务发起请求, 接收响应的过滤器
3. 经过routing filter路由过滤器, 最后会传递过post filter 后置过滤器,进行一些后续的处理, 这时候已经拿到响应了, 然后在返回给客户端.
4. 在这三个过滤器过滤的过程中,任何一个环节发生错误, 都会进入error filter. 有error filter进行统一的错误处理. error filter错误过滤器会发送给post filter, 也是以响应的方式发回给客户端.
这是一个请求, 在网关处理的生命周期.
三. 过滤器基本的概念
1. 类型:
它被定义在路由的流程中, 过滤器被应用的阶段. 有pre routing filter前置过滤器, routing filter路由过滤器, post routing filter 后置过滤器
2. 执行顺序Execution Order : 在同一个type中定义过滤器执行的顺序
每一种类型的过滤器都可能有一个或者多个过滤器, 比如pre routing filter可能有多个. 他们的执行顺序, 不是乱序执行的. 他们会有一个自定义的order顺序.
3. 条件Criteria: 过滤器执行必须满足的条件
在过滤器被执行,流转的时候, 某个过滤器到底要不要执行? 满足什么条件执行? 这就是过滤器条件定义的.
4. 动作Action
如果满足条件, 过滤器将要执行的动作是什么.
四. 标准的过滤器类型
1. pre:前置过滤器
在请求被路由到原服务器之前, 要执行的过滤器
- 认证 : 认证安全, 是否符合条件, 认证为安全的才能放过
- 选路由: 当前这个请求来了, 应该调用后面的哪个微服务呢? A还是B
- 请求日志: 请求日志, 日志来了, 写日志, 对其进行监控
2. routing: 路由过滤器
处理将请求发送到源服务器的过滤器
3. post
在响应从源服务器返回时要被执行的过滤器
- 对响应增加http请求头: 要增加调试的header日志
- 收集统计和度量: 这次请求, 它的性能如何, 有没有出错? 可以搜集一些信息
- 将响应以流的方式返回客户端
4. error
上述三种过滤器中任何过滤器出现错误都要执行的过滤器
五. zuul网关过滤器的样例
zuul网关过滤器是groovy的脚本, groovy脚本有一个特性是可以动态编译的. 上传的过滤器, 然后在zuul网关动态编译和加载.
下面是一个简单的前置路由过滤器
class DeviceDelayFilter extends ZuulFilter { // 这里定义过滤器的类型, pre, routing, post @Override String filterType() { return 'pre' } // 定义过滤器执行的顺序 @Override int filterOrder() { return 100 } // 定义过滤器执行的条件 boolean shouldFilter() { return RequestContext.getCurrentContext().getRouteHost() != null && RequestContext.getCurrentContext().sendZuulResponse() } // 定义过滤器执行的具体逻辑 Object run() { return null } }
方法的具体含义参考上面的注释.
zuul 有一个自己的过滤器管理的样例, 就是在zuul中定义了哪些过滤器
这个界面是生产过程需, 自己开发的一个管理界面.
asd