zuul 源码解析
1. RefreshableRouteLocatorRouteLocator
路由定位器,在 Spring Cloud Zuul 中,RouteLocator 的主要作用是加载 zuul 路由配置信息(如yml配置文件或数据库)到zuul中,再由过滤器将这些信息一步步去匹配,主要的 RouteLocator 有如下几种
SimpleRouteLocator
主要加载配置文件的路由规则
DiscoveryClientRouteLocator
服务发现的路由定位器,去注册中心如Eureka,consul等拿到服务名称,以这样的方式/服务名称/**映射成路由规则
CompositeRouteLocator
复合路由定位器,主要集成所有的路由定位器(如配置文件路由定位器,服务发现定位器,自定义路由定位器等)来路由定位。
RefreshableRouteLocator
路由刷新,只有实现了此接口的路由定位器才能被刷新
2. 核心过滤器
在Spring Cloud Zuul中,为了让API网关组件可以更方便的上手使用,它在HTTP请求生命周期的各个阶段默认地实现了一批核心过滤器,它们会在API网关服务启动的时候被自动地加载和启用。我们可以在源码中查看和了解它们,它们定义于spring-cloud-netflix-core模块的org.springframework.cloud.netflix.zuul.filters包下。
pre过滤器
- ServletDetectionFilter:它的执行顺序为-3,是最先被执行的过滤器。该过滤器总是会被执行,主要用来检测当前请求是通过Spring的DispatcherServlet处理运行,还是通过ZuulServlet来处理运行的。它的检测结果会以布尔类型保存在当前请求上下文的isDispatcherServletRequest参数中,这样在后续的过滤器中,我们就可以通过RequestUtils.isDispatcherServletRequest()和RequestUtils.isZuulServletRequest()方法判断它以实现做不同的处理。一般情况下,发送到API网关的外部请求都会被Spring的DispatcherServlet处理,除了通过/zuul/路径访问的请求会绕过DispatcherServlet,被ZuulServlet处理,主要用来应对处理大文件上传的情况。另外,对于ZuulServlet的访问路径/zuul/ ,我们可以通过zuul.servletPath参数来进行修改。
- Servlet30WrapperFilter:它的执行顺序为-2,是第二个执行的过滤器。目前的实现会对所有请求生效,主要为了将原始的HttpServletRequest包装成Servlet30RequestWrapper对象。
- FormBodyWrapperFilter:它的执行顺序为-1,是第三个执行的过滤器。该过滤器仅对两种类请求生效,第一类是Content-Type为application/x-www-form-urlencoded的请求,第二类是Content-Type为multipart/form-data并且是由Spring的DispatcherServlet处理的请求(用到了ServletDetectionFilter的处理结果)。而该过滤器的主要目的是将符合要求的请求体包装成FormBodyRequestWrapper对象。
- DebugFilter:它的执行顺序为1,是第四个执行的过滤器。该过滤器会根据配置参数zuul.debug.request和请求中的debug参数来决定是否执行过滤器中的操作。而它的具体操作内容则是将当前的请求上下文中的debugRouting和debugRequest参数设置为true。由于在同一个请求的不同生命周期中,都可以访问到这两个值,所以我们在后续的各个过滤器中可以利用这两值来定义一些debug信息,这样当线上环境出现问题的时候,可以通过请求参数的方式来激活这些debug信息以帮助分析问题。另外,对于请求参数中的debug参数,我们也可以通过zuul.debug.parameter来进行自定义。
- PreDecorationFilter:它的执行顺序为5,是pre阶段最后被执行的过滤器。该过滤器会判断当前请求上下文中是否存在forward.to和serviceId参数,如果都不存在,那么它就会执行具体过滤器的操作(如果有一个存在的话,说明当前请求已经被处理过了,因为这两个信息就是根据当前请求的路由信息加载进来的)。而它的具体操作内容就是为当前请求做一些预处理,比如:进行路由规则的匹配(设置 routeHost 至 request 域中)、在请求上下文中设置该请求的基本信息以及将路由匹配结果等一些设置信息等,这些信息将是后续过滤器进行处理的重要依据,我们可以通过RequestContext.getCurrentContext()来访问这些信息。另外,我们还可以在该实现中找到一些对HTTP头请求进行处理的逻辑,其中包含了一些耳熟能详的头域,比如:X-Forwarded-Host、X-Forwarded-Port。另外,对于这些头域的记录是通过zuul.addProxyHeaders参数进行控制的,而这个参数默认值为true,所以Zuul在请求跳转时默认地会为请求增加X-Forwarded-*头域,包括:X-Forwarded-Host、X-Forwarded-Port、X-Forwarded-For、X-Forwarded-Prefix、X-Forwarded-Proto。我们也可以通过设置zuul.addProxyHeaders=false关闭对这些头域的添加动作。
route过滤器
- RibbonRoutingFilter:它的执行顺序为10,是route阶段第一个执行的过滤器。该过滤器只对请求上下文中存在serviceId参数的请求进行处理,即只对通过serviceId配置路由规则的请求生效。而该过滤器的执行逻辑就是面向服务路由的核心,它通过使用Ribbon和Hystrix来向服务实例发起请求,并将服务实例的请求结果返回。
- SimpleHostRoutingFilter:它的执行顺序为100,是route阶段第二个执行的过滤器。该过滤器只对请求上下文中存在routeHost参数的请求进行处理,即只对通过url配置路由规则的请求生效。而该过滤器的执行逻辑就是直接向routeHost参数的物理地址发起请求,从源码中我们可以知道该请求是直接通过httpclient包实现的,而没有使用Hystrix命令进行包装,所以这类请求并没有线程隔离和断路器的保护。
- SendForwardFilter:它的执行顺序为500,是route阶段第三个执行的过滤器。该过滤器只对请求上下文中存在forward.to参数的请求进行处理,即用来处理路由规则中的forward本地跳转配置。
post过滤器
- SendErrorFilter:它的执行顺序为0,是post阶段第一个执行的过滤器。该过滤器仅在请求上下文中包含error.status_code参数(由之前执行的过滤器设置的错误编码)并且还没有被该过滤器处理过的时候执行。而该过滤器的具体逻辑就是利用请求上下文中的错误信息来组织成一个forward到API网关/error错误端点的请求来产生错误响应。
- SendResponseFilter:它的执行顺序为1000,是post阶段最后执行的过滤器。该过滤器会检查请求上下文中是否包含请求响应相关的头信息、响应数据流或是响应体,只有在包含它们其中一个的时候就会执行处理逻辑。而该过滤器的处理逻辑就是利用请求上下文的响应信息来组织需要发送回客户端的响应内容。

参考链接
Spring Cloud 源码分析(四)Zuul:核心过滤器
zuul 源码解析的更多相关文章
- zuul网关源码解析
zuul网关源码解析 zuul请求的生命周期 ZuulServlet ZuulServlet定义了对zuul整个过程的处理,如下: public void service(javax.servlet. ...
- springcloud源码解析(目录)
springcloud是一个基于springboot的一站式企业级分布式应用开发框架.springboot为其提供了创建单一项目的便利性,springcloud组合了现有的.常用的分布式项目的解决方案 ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- jQuery2.x源码解析(缓存篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...
- Spring IoC源码解析——Bean的创建和初始化
Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...
- jQuery2.x源码解析(构建篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...
- jQuery2.x源码解析(设计篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...
随机推荐
- 使用离线部署32B模型实现OpenDeepWiki项目代码自动分析与文档生成
背景介绍 在企业环境中,我们经常需要对公司项目代码进行分析和文档生成.然而,考虑到代码的保密性,将代码上传至公共AI平台存在安全隐患.为解决这一问题,我们可以在公司内部GPU服务器上部署强大的大语言模 ...
- Win32汇编学习笔记11.游戏辅助的实现
Win32汇编学习笔记11.游戏辅助的实现-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net 游戏基址 游戏基址的概念 游戏基址是保持恒定的两部分内存地址的一部分并提 ...
- Java 枚举类的简单介绍
综述 enum 的全称为 enumeration, 是Java1.5引入的新特性,通过关键字enum来定义枚举类.它是一种特殊类,和普通类一样可以使用构造器.定义成员变量和方法,也能实现一个或多个 ...
- openssl头文件出现DEPRECATEDIN_1_1_0导致引入头文件时程序无法编译
我使用的是unbuntu20.04版本中,通过apt安装的openssl,发现openssl中的多个库文件中会出现类似'DEPRECATEDIN_1_1_0(unsigned char *ASN1_S ...
- GoLand2023设置GitBash为默认命令行终端
修改设置中的终端配置,将其修改为你的git bash启动脚本,注意需要带-login -i: 验证成功:
- 关于js中的toLocaleDateString()方法
toLocaleDateString()方法是JavaScript Date对象的一个内建方法,它将日期转换为符合特定地区习惯的字符串格式. 基本用法: 如果没有传入任何参数,toLocaleDate ...
- k8s servicemonitor 采集超时配置
背景说明 我们有时候在编写exporter时,其中某个采集的metrics接口获取数据很慢,可能需要达到10-20S,基于此种情况,如果我们按照ServiceMonitor默认的配置进行,这里默认sc ...
- XXL-JOB分布式任务调度平台
简介 概述 XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并接入多家公司线上产品线,开箱即用. 特性 1.简单:支持通过Web页面对任务进行 ...
- TypeScript结构化类型初探
啥是鸭子类型? 作为一个前端程序员,想必大家都知道javascript是一个弱类型语言,如果需要类型的支持,那就需要借助typescript来实现,但是大家可曾听过这样一个说法? javascript ...
- css 给Input 左侧添加图标
background-image: url(../Content/Pc/img/IC_search.png); background-repeat: no-repeat; background-pos ...