springcloud gateway 源码解析、请求响应流程、第三方响应结果在 gateway 的经过

大家好,我是烤鸭:

1.  官方介绍

官方文档:

看的是 2.2.5.RELEASE 版本的

https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/

看一下官方这段说明,gateway 使用的是 webflux 和 reactor,有一些同步的包(data,security 可能不支持)。

还有就是需要netty作为服务器,传统的 servlet 模型和 war 包不支持。

工作流程:

简单说就是网关收到客户端的 request 之后经过一系列请求过滤器到代理的服务,收到 response之后,再经过一系列的响应过滤器返回到网关->客户端。

2.  源码分析

2.1  reactor 介绍

由于 gateway 是基于 reactor 的,先看下 reactor 的 Flux 和 Mono

reactor 是响应式编程,相对的传统模式 遍历-> 拉取 ->TODO ,而响应式 遍历(发布) -> 订阅者 -> TODO,是基于 发布 — 订阅的模式。

而 Flux 和 Mono 是 Reactor 中的两个基本概念。都实现 CorePublisher 接口。(用于发布的元素)

Flux 表示的是包含 0 到 N 个元素的异步序列。在该序列中可以包含三种不同类型的消息通知:正常的包含元素的消息、序列结束的消息和序列出错的消息。当消息通知产生时,订阅者中对应的方法 onNext(), onComplete()和 onError()会被调用。Mono 表示的是包含 0 或者 1 个元素的异步序列。该序列中同样可以包含与 Flux 相同的三种类型的消息通知。Flux 和 Mono 之间可以进行转换。对一个 Flux 序列进行计数操作,得到的结果是一个 Mono对象。把两个 Mono 序列合并在一起,得到的是一个 Flux 对象。

2.2 handler 和 filter

看了网上一些资料,从 ReactorHttpHandlerAdapter.apply 开始,debug 看看从哪发起的。

HttpServerHandle.onStateChange 这个是监听连接状态的方法,可以看到请求刚进来的时候是 request_received

HttpWebHandlerAdapter.apply ,包装模式,request 和 response,继续执行 handle方法,生成 exchange 对象,将 request ,response 还有其他的 attribute 封装到一个对象

之后进去 Dispatcherhandler.handle ,这里边会有3个操作,获取路由(getHandler)、请求路由(invokeHandler)、解析结果(handleResult)

获取路由:AbstractHandlerMapping.getHandler (代码没贴,有个判断 是否跨域配置的判断) 中间调用RoutePredicateHandlerMapping.getHandlerInternal,从RouteLocator 获取 路由信息

请求路由:默认走的是 SimpleHandlerAdapter.handle

FilteringWebHandler.handle,获取路由对象和对应的 filter,经过 过滤器链,默认是9个全局过滤器,主要看下 NettyRoutingFilter 和 NettyWriteResponseFilter

NettyRoutingFilter.filter 就是发送http请求,调用第三方服务,对response 请求头过滤处理,将response 封装到 Mono

NettyWriteResponseFilter.filter

可以看出来这时候netty 已经响应结果,并且往 exchange的reponse 写入

会判断响应的 content-type 是流还是其他的,如果是流的话,写入并刷新。这个地方看一下 wrap 方法,我找了半天都没有找到 gateway 在哪保存的第三方服务的返回值,就在这个byteBuf,封装 DataBuffer,设置到 DataBufferFactory,和 response 绑定。

看一下 wrap 方法

之后的方法调用 ReactorServerHttpResponse.writeWithInternal ,感兴趣可以看出,代码就不贴了。

由于 SimpleHandlerAdapter 返回的是 `Mono.empty()` ,所以不会触发 handleResult 方法。

其中还有HttpServerHandle.onStateChange 监听到其他的状态,也不贴了。

3.  总结

以上就是 gateway 收到请求后,到返回一系列的流程,内容也不是特别全。

监听到请求进入:HttpServerHandle.onStateChange(newState = request_received) ->

包装 request和response:ReactorHttpHandlerAdapter.apply ->

生成 exchange(包含 request和 response),用于netty请求 : HttpWebHandlerAdapter.apply ->

获取路由、请求路由、解析结果:Dispatcherhandler.handle ->

获取路由 AbstractHandlerMapping.getHandler:-> RoutePredicateHandlerMapping.getHandlerInternal

请求路由:SimpleHandlerAdapter.handle:-> FilteringWebHandler.handle

默认9个全局过滤器:

发送http请求,调用第三方服务,对response 请求头过滤处理,将response 封装到 Mono:NettyRoutingFilter.filter

获取netty 响应结果,并且往 exchange的reponse 写入:NettyWriteResponseFilter.filter

结果解析:ResponseBodyResultHandler.handleResult (由于 SimpleHandlerAdapter 返回的是 Mono.empty(),所以不会触发 handleResult 方法)

写入response并返回:NettyWriteResponseFilter.wrap (byteBuf,封装 DataBuffer,设置到 DataBufferFactory,和 response 绑定)

 

所以看到有一些想在网关层面修改 response 的需求,只需要增加一个filter 修改 response绑定的 DataBufferFactory 中的 DataBuffer 即可。

 

还有一些不错的文章推荐:

https://developer.ibm.com/zh/articles/j-cn-with-reactor-response-encode/

https://blog.csdn.net/chengqiuming/article/details/103394337

https://www.jianshu.com/p/c40a757fad01

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/412612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

改logback logstash-logback-encoder 框架本身的日志级别

大家好,我是烤鸭: 最近遇到一个问题,想把logback框架本身的日志级别修改,需要 logstash-logback-encoder 6.1 以上的版本才可以。 直接上代码 这里修改的不是业务日志级别,是 logback 框架本身(确切地说是 logstash…

idea首次创建新模块的详细操作

依赖网址:https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api/3.1.0 https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api/2.3.1 https://mvnrepository.com/artifact/org.springframework/spring-webmvc 创建文件夹 修改版本号 配…

markdown 常用语法总结 - 个人版

这里并不是要总结所有的 markdown 语法,只是总结笔者自己撰写博客时常用的一些 markdown 语法。 1 图片设置 1.1 设置图片位置 利用markdown在编写文档时插入图片是默认靠左,有些时候将图片设置为居中时可以更加的美观,这时就需要在图片的信息…

PostgreSQL 、springboot 、spring data jpa 集成

项目地址:https://gitee.com/zhxs_code/PostgreSQL_springboot_jpa_demo.git 增删查改都已经实现。 重点部分: 1.定义自己的方言。 1 package com.zxl.postgrespringdemo.config.dialect;2 3 import org.hibernate.dialect.PostgreSQL94Dialect;4 import…

RedisTemplate value序列化导致的问题

大家好,我是烤鸭: ​ 今天分享一个redisTemplate 使用时,value 序列化的问题。 1. 问题描述 其实我最开始遇到的问题是: stringRedisTemplate.opsForSet().isMember(key,value)一直返回false问题,下边博客给出了…

[css] 如何实现换肤功能?

[css] 如何实现换肤功能? css 换肤常见方案 是通过 less/sass/postcss 等css 预处理器,通过它们自身的变量用法,设置不同变量,生成不同的主题样式,但是这些样式都是会被打包成常量,我们只能在编译之前修改…

日志 中文乱码、nacos 中文乱码、saltstack 中文乱码、docker中文乱码

大家好,我是烤鸭: ​ 今天分享一个 saltstack 中文乱码 的问题。 问题说明 由于项目之前没有接入公司的发布系统,今天接入之后发现日志乱码,不仅如此,从nacos获取到的中文参数也是乱码。于是猜想是发布系统遗留了一…

redis出现过多command 慢查询slowlog出现command命令

大家好,我是烤鸭: 今天分享一个问题,一个关于redis slowlog,执行过多 command命令的问题。 问题来源 所有走redis 的接口tp99和平均耗时是原来的两倍不止,运维说redis 的qps也翻倍了。查了下slowlog,发现…

springcloud gateway 使用nacos 动态过滤器 记一次线上网关升级cpu升高的问题

大家好,我是烤鸭: ​ 网关升级,想使用 springcloud gateway nacos 动态过滤器配置(原来是硬编码的方式),升级之后出了一些问题(cpu升高,ygc频繁),记录一下。 关于 springcloud gateway 集成 nacos 可以看…

【1】生产者-消费者模型的三种实现方式

(手写生产者消费者模型,写BlockingQueue较简便 ) 1、背景 生产者生产数据到缓冲区中,消费者从缓冲区中取数据。 如果缓冲区已经满了,则生产者线程阻塞; 如果…

springboot mybatis-plus 配置 yml 、druid 配置 yml 、mybatis-plus 代码生成

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下 springboot mybatis-plus 和 druid 的yml 配置文件。 pom <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency…

实验吧Web-易-天网管理系统(php弱类型,==号)

打开网页&#xff0c;查看源码&#xff0c;看到 <!-- $test$_GET[username]; $testmd5($test); if($test0) --> 说明用户名需要加密之后为0。 对于PHP的号&#xff0c;在使用 运算符对两个字符串进行松散比较时&#xff0c;PHP会把类数值的字符串转换为数值进行比较&…

个人的博客搭建(持续更新)

最近的CSDN的博客阅读体验非常的糟糕&#xff0c;恰好自己也一直想搭建一个属于自己的网站&#xff0c;放下自己的技术心得情感体会&#xff0c;从零开始慢慢搭建项目磨练技术&#xff0c;以后也把自己新习得的技术放在里面增加自己的学习乐趣。 一&#xff0c;搭建基本的项目模…

用Java实现图片验证码功能

一、什么是图片验证码&#xff1f; 可以参考下面这张图&#xff1a; 我们在一些网站注册的时候&#xff0c;经常需要填写以上图片的信息。 1、图片生成实体类&#xff1a; 1 package com.hexianwei.graphic;2 3 import java.awt.Color;4 import java.awt.Font;5 import java.aw…

nacos配置刷新失败导致的cpu上升和频繁重启,nacos配置中心源码解析

大家好&#xff0c;我是烤鸭&#xff1a; nacos 版本 1.3.2&#xff0c;先说下结论&#xff0c;频繁重启的原因确实没有找到&#xff0c;跟nacos有关&#xff0c;日志没有保留多少&#xff0c;只能从源码找下头绪(出问题的版本 server用的是 nacos 1.1&#xff0c;nacos-client…

nova— 计算服务

一、nova介绍&#xff1a; Nova 是 OpenStack 最核心的服务&#xff0c;负责维护和管理云环境的计算资源。OpenStack 作为 IaaS 的云操作系统&#xff0c;虚拟机生命周期管理也就是通过 Nova 来实现的。用途与功能 :1) 实例生命周期管理2) 管理计算资源3) 网络和认证管理4)REST…

springcloud gateway 自定义 accesslog elk

大家好&#xff0c;我是烤鸭&#xff1a; ​ 最近用 springcloud gateway 时&#xff0c;想使用类似 logback-access的功能&#xff0c;用来做数据统计和图表绘制等等&#xff0c;发现没有类似的功能&#xff0c;只能自己开发了。 环境&#xff1a; <dependency><gr…

jenkins发布docker项目 harbor

大家好&#xff0c;我是烤鸭&#xff1a; ​ jenkins 部署k8s 项目还是比较流畅的&#xff0c;本身建立多流水线项目&#xff0c;在项目中添加jenkinsfile就好了&#xff0c;镜像需要额外的参数&#xff0c;还可以添加dokcerfile文件。由于我现在的问题是不能够修改原有的项…

saltstack部署java应用失败无日志——CICD 部署

大家好&#xff0c;我是烤鸭&#xff1a; ​   最近在搞公司的CICD&#xff0c;遇到各种问题。复盘总结一下。 CICD 架构 这篇文章写得很详细&#xff0c;可以看一下 https://linux.cn/article-9926-1.html 而这里只是结合现在的情况分析下&#xff1a; CI 持续集成&…

[css] 浏览器是怎样判断元素是否和某个CSS选择器匹配?

[css] 浏览器是怎样判断元素是否和某个CSS选择器匹配&#xff1f; 有选择器&#xff1a; div.ready #wrapper > .bg-red 先把所有元素 class 中有 bg-red 的元素拿出来组成一个集合&#xff0c;然后上一层&#xff0c;对每一个集合中的元素&#xff0c;如果元素的 parent i…