SpringCloud Gateway中GatewayFilterChain执行流程详解

上一节我们把FilteringWebHandler中handle方法的过滤器统一排序的那部分逻辑讲完了

接着就是生成过滤器器链,执行过滤方法

return new DefaultGatewayFilterChain(combined).filter(exchange);
		@Override
		public Mono<Void> filter(ServerWebExchange exchange) {
			return Mono.defer(() -> {
				if (this.index < filters.size()) {
                      //filters就是上面传入的所有过滤器,index就是当前的索引
					GatewayFilter filter = filters.get(this.index);
                      //index+1,获取下一个过滤器
					DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
                      //分别执行每个过滤器的filter方法
					return filter.filter(exchange, chain);
				}
				else {
					return Mono.empty(); // complete
				}
			});
		}
	}

可以看到目前系统内置的过滤器有十种,每个过滤器大致的作用我在下面列出来可供参考

RemoveCachedBodyFilter:移除请求上下文中的body缓存信息,只有在使用了ReadBodyPredicateFactory相关处理是会有body缓存

AdaptCachedBodyGlobalFilter:从请求中获取body缓存到网关上下文,这样就可以直接从网关上下文中拿到请求参数,而不会出现从request中拿到之后还要回填到请求体的问题

NettyWriteResponseFilter:进行响应回写,但是大家可以注意到执行器链中NettyWriteResponseFilter的排序是在很前面的,按道理这种响应处理的类应该是在靠后才对,这里的设计比较巧妙。大家可以看到chain.filter(exchange).then(),意思就是执行到我的时候直接跳过下一个,等后面的过滤器都执行完后才执行这段逻辑。

ForwardPathFilter:解析路径并且将路径转发

RouteToRequestUrlFilter:根据匹配的 Route ,计算请求的地址

ReactiveLoadBalancerClientFilter:根据 lb:// 前缀过滤处理,做负载均衡,选择最终要调用的服务地址

LoadBalancerServiceInstanceCookieFilter:也是负载均衡相关,并且和ServiceInstance有关

WebsocketRoutingFilter:Websocket 路由网关过滤器。其根据 ws://wss:// 前缀过滤处理,代理后端 Websocket 服务,提供给客户端连接

NettyRoutingFilter:Netty 路由网关过滤器。其根据 http://https:// 前缀过滤处理,使用基于 Netty 实现的 HttpClient 请求后端 Http 服务

ForwardRoutingFilter:转发路由网关过滤器。其根据 forward:// 前缀过滤处理,将请求转发到当前网关实例本地接口。

那么请求最后是怎么转发到controller那进行处理的呢?

其实是在NettyRoutingFilter里面,通过httpClient来发送request,下面截取一部分代码

		Flux<HttpClientResponse> responseFlux = getHttpClient(route, exchange).headers(headers -> {
			headers.add(httpHeaders);
			// Will either be set below, or later by Netty
			headers.remove(HttpHeaders.HOST);
			if (preserveHost) {
				String host = request.getHeaders().getFirst(HttpHeaders.HOST);
				headers.add(HttpHeaders.HOST, host);
			}
		}).request(method).uri(url).send((req, nettyOutbound) -> {
			if (log.isTraceEnabled()) {
				nettyOutbound.withConnection(connection -> log.trace("outbound route: "
						+ connection.channel().id().asShortText() + ", inbound: " + exchange.getLogPrefix()));
			}
             //具体调用发送request的位置
			return nettyOutbound.send(request.getBody().map(this::getByteBuf));

Spring-Cloud-Gateway总体的执行流程到这就差不多分享完了,后续可能继续会分享一些关于路由或者网关一些其他的扩展知识。

到此这篇关于SpringCloud Gateway中GatewayFilterChain执行流程详解的文章就介绍到这了,更多相关SpringCloud GatewayFilterChain内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot 中的 Filter 实现超大响应 JSON 数据压缩的方法

    目录 简介 pom.xml 引入依赖 对Response进行包装 定义GzipFilter对输出进行拦截 注册 GzipFilter 拦截器 定义 Controller 定义 Springboot 引导类 测试 简介 项目中,请求时发送超大 json 数据外:响应时也有可能返回超大 json数据.上一篇实现了请求数据的 gzip 压缩.本篇通过 filter 实现对响应 json 数据的压缩.先了解一下以下两个概念: 请求头:Accept-Encoding : gzip告诉服务器,该浏览器支持

  • 详解SpringCloud Gateway之过滤器GatewayFilter

    在Spring-Cloud-Gateway之请求处理流程文中我们了解最终网关是将请求交给过滤器链表进行处理,接下来我们阅读Spring-Cloud-Gateway的整个过滤器类结构以及主要功能 通过源码可以看到Spring-Cloud-Gateway的filter包中吉接口有如下三个,GatewayFilter,GlobalFilter,GatewayFilterChain,下来我依次阅读接口的主要实现功能. GatewayFilterChain 类图 代码 /** * 网关过滤链表接口 * 用

  • springboot中filter的用法详解

    一.在spring的应用中我们存在两种过滤的用法,一种是拦截器.另外一种当然是过滤器.我们这里介绍过滤器在springboot的用法,在springmvc中的用法基本上一样,只是配置上面有点区别. 二.filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter

  • spring cloud-zuul的Filter使用详解

    在前面我们使用zuul搭建了网关http://www.jb51.net/article/133235.htm 关于网关的作用,这里就不再次赘述了,我们今天的重点是zuul的Filter.通过Filter,我们可以实现安全控制,比如,只有请求参数中有用户名和密码的客户端才能访问服务端的资源.那么如何来实现Filter了? 要想实现Filter,需要以下几个步骤: 1.继承ZuulFilter类,为了验证Filter的特性,我们这里创建3个Filter 根据用户名来过滤 package com.ch

  • Spring Security CsrfFilter过滤器用法实例

    这篇文章主要介绍了Spring Security CsrfFilter过滤器用法实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 spring security框架提供的默认登录页面,会有一个name属性值为_csrf的隐藏域: 这是框架在用户访问登录页面之前就生成的,保存在内存中,当用户提交表单的时候会跟着一起提交:_csrf_formdata 然后会经过spring security框架resources目录下配置文件spring-sec

  • SpringMvc框架的简介与执行流程详解

    目录 一.SpringMvc框架简介 1.Mvc设计理念 2.SpringMvc简介 二.SpringMvc执行流程 1.流程图解 2.步骤描述 3.核心组件 三.整合Spring框架配置 1.spring-mvc配置 2.Web.xml配置 3.测试接口 4.常用注解说明 四.常见参数映射 1.普通映射 2.指定参数名 3.数组参数 4.Map参数 5.包装参数 6.Rest风格参数 五.源代码地址 一.SpringMvc框架简介 1.Mvc设计理念 M:代表模型Model 模型就是数据,应用

  • Mysql表连接的执行流程详解

    目录 1. 前言 1.1 mysql连接的原理 1.2 show warnings命令 2. 准备工作 3. inner join内连接on.where的区别 4. left join左连接on.where的区别 4.1 where驱动表过滤条件 4.2 on驱动表过滤条件 4.3 on被驱动表过滤条件 4.4 where被驱动表过滤条件 5. 总结 1. 前言 对于连接操作,驱动表和被驱动表的关联条件我们放在on后面,如果额外增加对驱动表和被驱动表的过滤条件,放到on或者where后面都不会报

  • ThreadPoolExecutor参数含义及源码执行流程详解

    目录 背景 典型回答 考点分析 知识拓展 execute() VS submit() 线程池的拒绝策略 自定义拒绝策略 ThreadPoolExecutor 扩展 小结 背景 线程池是为了避免线程频繁的创建和销毁带来的性能消耗,而建立的一种池化技术,它是把已创建的线程放入“池”中,当有任务来临时就可以重用已有的线程,无需等待创建的过程,这样就可以有效提高程序的响应速度.但如果要说线程池的话一定离不开 ThreadPoolExecutor ,在阿里巴巴的<Java 开发手册>中是这样规定线程池的

  • SpringCloud注册中心部署Eureka流程详解

    目录 1.Eureka服务 2.服务提供者 3.服务消费者 4.服务调用测试 今天我们开始正式编码,如何创建spring boot项目这篇文章就不再讲述,如果想要了解可以阅读我之前的创建springboot项目. 首先我们先进行Spring cloud五大组件之一的注册中心,之前文章已经讲过注册中心的介绍,今天我们来部署Netflix的Eureka,进行单机部署以及高可用部署,并开发生产者以及消费者来进行测试eureka的注册消费.(ps:系列文章使用的Spring cloud版本为2021.0

  • Handler消息传递机制类引入及执行流程详解

    目录 提要 1.学习路线图: 2.Handler类的引入 3.Handler的执行流程图 4.Handler的相关方法 5.Handler的使用示例 1)Handler写在主线程中 2)Handler写在子线程中 提要 本节给大家讲解的是Activity中UI组件中的信息传递Handler,相信很多朋友都知道,Android为了线程安全,并不允许我们在UI线程外操作UI:很多时候我们做界面刷新都需要通过Handler来通知UI组件更新!除了用Handler完成界面更新外,还可以使用runOnUi

  • Go中init()执行顺序详解

    目录 概述 init()函数 执行时机 概述 init()一般用来做一些初始化工作, go允许定义多个init(),根据init()重复场景不同,可以分为 同文件 单文件中定义多个init() 同模块 同模块下不同文件中定义了多个init() 子模块 本模块和子模块都包含init() 跨模块 多个被引用模块中均含init() 要点秘诀: 涉及引用时,先加载的先执行 同一文件中,先定义的先执行 init()函数 init()函数没有参数,也没有返回值. init()函数在程序运行时,自动自动被调用

  • mysql基础:mysqld_safe 启动执行流程详解

    mysqld_safe脚本执行的基本流程:1.查找basedir和ledir.2.查找datadir和my.cnf.3.对my.cnf做一些检查,具体检查哪些选项请看附件中的注释.4.解析my.cnf中的组[mysqld]和[mysqld_safe]并和终端里输入的命令合并.5.调用parse_arguments函数解析用户传递的所有参数($@).6.对系统日志和错误日志的判断和相应处理具体可以参考附件中的注释,及选项--err-log参数的赋值.7.对选项--user,--pid-file,-

  • AngularJS执行流程详解

    一.启动阶段 浏览器解析HTML页面,读取到angular.js的<script>标签后会停止解析后面的DOM节点,开始执行angular.js,与此同时,Angular会设置一个事件监听器来监听DOMContentLoaded事件,当Angular监听到这个事件后,Angular就启动了. 二.初始化阶段 Angular启动后,它会查找ng-app指令,然后初始化一系列必要的组件(即$injector.$compile服务以及$rootScope),接着继续解析DOM. 三.编译.链接阶段

  • SpringCloud项目的log4j2漏洞解决方案详解流程

    步骤如下: <properties> <log4j2.version>2.15.0</log4j2.version> </properties> 下面为上边对应版本号的具体依赖 <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.15.

  • MySQL执行SQL语句的流程详解

    目录 1.通常sql执行流程 1.1 问题1:MySQL谁去处理网络请求? 1.2 问题2:MySQL如何执行sql语句? 1.3 查询解析器 1.4 查询优化器 1.5 存储引擎 1.6 执行器 2.总结 1.通常sql执行流程 用户发起请求到业务服务器,执行sql语句时,先到连接池中获取连接,然后到mysql服务器执行查询. 1.1 问题1:MySQL谁去处理网络请求? msyql服务器谁负责从这个连接中去监听这个网络请求?谁负责从网络连接里把数据读出来? 其实大家都知道,网络连接必须得分配

随机推荐