Spring Cloud Gateway 缓存区异常

目录

1、问题背景

2、分析源码过程

3、解决办法


最近在测试环境spring cloud gateway突然出现了异常,在这里记录一下,直接上干货

1、问题背景

测试环境spring cloud gateway遇到以下异常

DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144(超出了缓冲区的最大字节数限制)

乍一看,问题很简单啊,通过配置加大缓存区不就行了啊,于是就在application.yml加了以下配置

#将缓存区设置为2m
spring:codec:max-in-memory-size: 2MB

可是问题又出现了,通过调试发现配置的max-in-memory-size在程序启动初始化确实是生效的。但是有业务调用的时候,此参数的接收值为null,maxInMemorySize还是读取的默认值(256K)。

那咋整,只能从源码入手了。

2、分析源码过程

通过异常日志,可以定位到异常位置

后来发现我们自定义的拦截器获取body的信息是获取方式,代码如下

因为HandlerStrategies.withDefaults() 是每次都需要重新创建对象,并非是spring注入的对象,所以每次获取的都是默认值,导致配置不生效。

3、解决办法

在我们自定的拦截器中注入ServerCodecConfigurer类,通过该类获取配置。这样获取到的就是我们在application.yml中配置的缓存区配置的字节数限制了。

具体代码:

@Component
@Slf4j
public class RequestFilter implements GlobalFilter, Ordered {@Overridepublic int getOrder() {return OrderedConstant.HIGHEST_PRECEDENCE;}//手动注入ServerCodecConfigurer@AutowiredServerCodecConfigurer codecConfigurer;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {StopWatch stopWatch = new StopWatch();stopWatch.start();long startTime = System.currentTimeMillis();try {final Log logDTO = new Log();ServerHttpRequest request = exchange.getRequest();// 设置X-Request-IdAtomicReference<String> requestId = new AtomicReference<>(GenerateIdUtils.requestIdWithUUID());Consumer<HttpHeaders> httpHeadersConsumer = httpHeaders -> {String headerRequestId = request.getHeaders().getFirst(HeaderConstant.REQUEST_ID);if (!Strings.isNullOrEmpty(headerRequestId)) {requestId.set(headerRequestId);}logDTO.setRequestId(requestId.get());httpHeaders.set(HeaderConstant.REQUEST_ID, requestId.get());httpHeaders.set(HeaderConstant.START_TIME_KEY, String.valueOf(startTime));};// codecConfigurer.getReaders()获取pplication.yml中配置的缓存区配置的字节数ServerRequest serverRequest = ServerRequest.create(exchange,codecConfigurer.getReaders());URI requestUri = request.getURI();String uriQuery = requestUri.getQuery();String url = requestUri.getPath() + (!Strings.isNullOrEmpty(uriQuery) ? "?" + uriQuery : "");HttpHeaders headers = request.getHeaders();MediaType mediaType = headers.getContentType();String method = request.getMethodValue().toUpperCase();// 原始请求体final AtomicReference<String> requestBody = new AtomicReference<>();final AtomicBoolean newBody = new AtomicBoolean(false);if (mediaType != null && LogHelper.isUploadFile(mediaType)) {requestBody.set("上传文件");} else {if (method.equals("GET")) {if (!Strings.isNullOrEmpty(uriQuery)) {requestBody.set(uriQuery);}} else {newBody.set(true);}}logDTO.setLevel(Log.LEVEL.INFO);logDTO.setRequestUrl(url);logDTO.setRequestBody(requestBody.get());logDTO.setRequestMethod(method);logDTO.setIp(IpUtils.getClientIp(request));ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate().headers(httpHeadersConsumer).build();ServerWebExchange build = exchange.mutate().request(serverHttpRequest).build();return build.getSession().flatMap(webSession -> {logDTO.setSessionId(webSession.getId());if (newBody.get() && headers.getContentLength() > 0) {Mono<String> bodyToMono = serverRequest.bodyToMono(String.class);return bodyToMono.flatMap(reqBody -> {logDTO.setRequestBody(reqBody);// 重写原始请求ServerHttpRequestDecorator requestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) {@Overridepublic Flux<DataBuffer> getBody() {NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false));DataBuffer bodyDataBuffer = nettyDataBufferFactory.wrap(reqBody.getBytes());return Flux.just(bodyDataBuffer);}};return chain.filter(exchange.mutate().request(requestDecorator).build()).then(LogHelper.doRecord(logDTO));});} else {return chain.filter(exchange).then(LogHelper.doRecord(logDTO));}});} catch (Exception e) {log.error("请求日志打印出现异常", e);return chain.filter(exchange);}}}

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

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

相关文章

Docker nginx容器代理播放m3u8视频文件(HLS)

文章目录 Docker Nginx容器代理播放M3U8文件教程获取Nginx Docker镜像设置Nginx配置文件用 ffmpeg 将 MP4 文件转换成 m3u8 文件运行Docker容器测试M3U8流其他问题我用vlc都能播放http://192.168.121.50/forest4kTest.m3u8和http://192.168.121.50/forest4kTest.mp4&#xff0c…

【HBase】——优化

1 RowKey设计 重要&#xff1a;一条数据的唯一标识就是 rowkey&#xff0c;那么这条数据存储于哪个分区&#xff0c;取决于 rowkey 处于 哪个一个预分区的区间内&#xff0c;设计 rowkey的主要目的 &#xff0c;就是让数据均匀的分布于所有的 region 中&#xff0c;在一定程度…

HTML 使用 ruby 给汉字加拼音

使用 ruby 给汉字加拼音 兼容性 使用 ruby 给汉字加拼音 大家有没有遇到过要给汉字头顶上加拼音的需求? 如果有的话, 你是怎么解决的呢? 如果费尽心思, 那么你可能走了很多弯路, 因为 HTML 原生就有这样的标签来帮我们实现类似的需求. <ruby> ruby 本身是「红宝石」…

大学物理-实验篇——测量误差与数据处理(测量分类、误差、有效数字、逐差法)

目录 测量分类 测量次数角度 测量条件角度 误差 误差分类 系统误差 随机误差 异常值 误差描述 精密度&#xff08;Precision&#xff09; 正确度&#xff08;Trueness&#xff09; 准确度/精确度&#xff08;Accuracy&#xff09; 随机误差的处理 直接测量 算术…

一起玩儿物联网人工智能小车(ESP32)——27. 旋转编码器的使用方法

摘要&#xff1a;本文介绍旋转编码器的使用方法 旋转编码器是一种机电设备&#xff0c;可将轴或轴的角位置或运动转换为模拟或数字输出信号&#xff0c;在工业控制中发挥着举足轻重的作用。旋转编码器目前被广泛的应用在数控机床、印刷设备、包装机械、输送带、电梯、机器人、风…

WeNet语音识别+Qwen-72B-Chat Bot+Sambert-Hifigan语音合成

WeNet语音识别Qwen-72B-Chat Bot&#x1f47e;Sambert-Hifigan语音合成 简介 利用 WeNet 进行语音识别&#xff0c;使用户能够通过语音输入与系统进行交互。接着&#xff0c;Qwen-72B-Chat Bot作为聊天机器人接收用户的语音输入或文本输入&#xff0c;提供响应并与用户进行对话…

Docker overlay2文件busy,容器不能删除问题解决

文章目录 在删除docker容器的时候报错,说设备正忙通过 docker ps -a 查看有两个状态的dead的容器解决方法&#xff1a;1.查看所有挂载的设备2.截取设备的进程id3.清理进程(kill掉即可) 在删除docker容器的时候报错,说设备正忙 Error response from daemon: Driver overlay2 fai…

【ARMv8架构系统安装PySide2】

ARMv8架构系统安装PySide2 Step1. 下载Qt资源包Step2. 配置和安装Qt5Step3. 检查Qt-5.15.2安装情况Step4. 安装PySide2所需的依赖库Step5. 下载和配置PySide2Step6. 检验PySide2是否安装成功 Step1. 下载Qt资源包 if you need the whole Qt5 (~900MB): wget http://master.qt…

Meshlab界面和菜单初步认识

文章目录 界面认识菜单 界面认识 顾名思义&#xff0c;MeshLab即网格实验室&#xff0c;用于处理三维对象&#xff0c;并有着针对网格基于网格操作的各种工具&#xff0c;是一个功能强大的三维几何处理系统。因其开源&#xff0c;直接搜官网下载即可。安装过程无坑&#xff0c…

vue icon 本地正常 线上打包失败变乱码

出现这个原因是因为sass解析的问题 Node版本高的话可以通过升级sass版本 并且配置vue.config规避这个问题 //给sass配置的东西 这个对应的版本是sass 1.39.0 本人node版本v14 升级sass版本后出现报错css: {loaderOptions: {scss: {additionalData: import "/styles/var…

C#,入门教程(10)——常量、变量与命名规则的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(09)——运算符的基础知识https://blog.csdn.net/beijinghorn/article/details/123908269 C#用于保存计算数据的元素&#xff0c;称为“变量”。 其中一般不改变初值的变量&#xff0c;称为常变量&#xff0c;简称“常量”。 无论…

nginx 二、配置域名

文章目录 一、配置本地域名查看虚拟机ip修改hosts文件测试域名是否配置成功 二、配置aliyun域名三、实践1.创建html2.配置nginx3.测试服务器内部测试页面测试 总结 docker中启动nginx容器完成如下操作&#xff0c;对于docker安装nginx可以看这篇文章 nginx 一、安装与conf浅析 …

zookeeper应用场景之分布式的ID生成器

1. 分布式ID生成器的使用场景 在分布式系统中&#xff0c;分布式ID生成器的使用场景非常之多&#xff1a; 大量的数据记录&#xff0c;需要分布式ID。大量的系统消息&#xff0c;需要分布式ID。大量的请求日志&#xff0c;如restful的操作记录&#xff0c;需要唯一标识&#x…

element中Tree 树形控件实现多选、展开折叠、全选全不选、父子联动、默认展开、默认选中、默认禁用、自定义节点内容、可拖拽节点、手风琴模式

目录 1.代码实现2. 效果图3. 使用到的部分属性说明4. 更多属性配置查看element官网 1.代码实现 <template><div class"TreePage"><el-checkboxv-model"menuExpand"change"handleCheckedTreeExpand($event, menu)">展开/折叠&l…

如何保障集团下达的政策要求有效落地

随着新一轮国企改革的推进&#xff0c;很多国有企业建立了集团化的管控体系。通过集团化经营管理的模式&#xff0c;帮助国有企业凝聚更强的竞争力&#xff0c;集团企业通过资源整合、反向投资、控股、参股等手法创造业务板块之间的协同、互补效应&#xff0c;从而实现战略联动…

gitlab 配置 二

一 环境说明 群晖Nas DS418DELL XPS serverGitlab ce 二 需要实现的功能 外网可以访问&#xff0c;gitlab使用https的方式访问。wiki issue 等都可以上传图片和附件。 三 操作步骤 因为群晖上有证书&#xff0c;并且由群晖做转发功能。因此证书上&#xff0c;采用群晖的证书…

Sqlmap参数设置

Sqlmap参数设置 &#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388; --------------------------------------------注意---------…

RBAC基于角色的访问控制

一 什么是RBAC 概念 RBAC 是基于角色的访问控制&#xff08;Role-Based Access Control &#xff09;在 RBAC 中&#xff0c;权限与角色相关联&#xff0c;用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的&#…

【论文阅读笔记】医学多模态新数据集-Large-scale Long-tailed Disease Diagnosis on Radiology Images

这是复旦大学2023.12.28开放出来的数据集和论文&#xff0c;感觉很宝藏&#xff0c;稍微将阅读过程记录一下。 Zheng Q, Zhao W, Wu C, et al. Large-scale Long-tailed Disease Diagnosis on Radiology Images[J]. arXiv preprint arXiv:2312.16151, 2023. 项目主页&#xf…

智慧校园的“边缘智能“: 打造未来教育的桥梁

在科技飞速发展的时代&#xff0c;智能已经渗透到我们生活的各个角落。而当智能遇上教育&#xff0c;会激发出怎样的火花呢&#xff1f;今天&#xff0c;我们就来聊聊这个热门话题——智慧校园和边缘智能网关的结合&#xff0c;它们是如何共同塑造未来教育的新形态。 什么是边…